List:Commits« Previous MessageNext Message »
From:Alexander Nozdrin Date:December 4 2008 11:14pm
Subject:bzr commit into mysql-6.0-runtime branch (alik:2765)
View as plain text  
#At file:///mnt/raid/alik/MySQL/bzr/00.merges/6.0-rt.merge/

 2765 Alexander Nozdrin	2008-12-05 [merge]
      Merge from 6.0
removed:
  mysql-test/suite/backup/r/backup_commit_blocker.result
  mysql-test/suite/backup/r/backup_view_on_view.result
  mysql-test/suite/backup/t/backup_commit_blocker.test
  mysql-test/suite/backup/t/backup_view_on_view.test
  mysql-test/suite/falcon/r/falcon_bug_28095_II.result
  mysql-test/suite/falcon/t/falcon_bug_28095_II-master.opt
  mysql-test/suite/falcon/t/falcon_bug_28095_II.test
added:
  mysql-test/include/restart_mysqld.inc
  mysql-test/include/wait_until_disconnected.inc
  mysql-test/suite/backup/r/backup_logs_purge.result
  mysql-test/suite/backup/r/backup_vp_nontx.result
  mysql-test/suite/backup/r/backup_vp_tx.result
  mysql-test/suite/backup/t/backup_logs_output-master.opt
  mysql-test/suite/backup/t/backup_logs_purge.test
  mysql-test/suite/backup/t/backup_nodata_driver-master.opt
  mysql-test/suite/backup/t/backup_vp_nontx.test
  mysql-test/suite/backup/t/backup_vp_tx.test
  mysql-test/suite/backup_engines/r/backup_tmp_tables.result
  mysql-test/suite/backup_engines/t/backup_tmp_tables.test
  mysql-test/suite/backup_engines/t/disabled.def
  mysql-test/suite/falcon/r/falcon_bug_30124-big.result
  mysql-test/suite/falcon/r/falcon_bug_38186.result
  mysql-test/suite/falcon/r/falcon_bug_39708.result
  mysql-test/suite/falcon/r/falcon_bug_40130.result
  mysql-test/suite/falcon/r/falcon_bug_40158.result
  mysql-test/suite/falcon/t/falcon_bug_30124-big.test
  mysql-test/suite/falcon/t/falcon_bug_38186.test
  mysql-test/suite/falcon/t/falcon_bug_39708-master.opt
  mysql-test/suite/falcon/t/falcon_bug_39708.test
  mysql-test/suite/falcon/t/falcon_bug_40130.test
  mysql-test/suite/falcon/t/falcon_bug_40158.test
  mysql-test/suite/rpl/r/rpl_backup.result
  mysql-test/suite/rpl/t/rpl_backup.test
  mysql-test/suite/sys_vars/t/disabled.def
renamed:
  mysql-test/suite/falcon/r/falcon_bug_28095_I.result => mysql-test/suite/falcon/r/falcon_bug_28095.result
  mysql-test/suite/falcon/t/falcon_bug_28095_I.test => mysql-test/suite/falcon/t/falcon_bug_28095.test
modified:
  client/mysqltest.c
  configure.in
  include/my_base.h
  mysql-test/include/wait_until_connected_again.inc
  mysql-test/lib/mtr_report.pl
  mysql-test/mysql-test-run.pl
  mysql-test/r/implicit_commit.result
  mysql-test/suite/backup/r/backup.result
  mysql-test/suite/backup/r/backup_backupdir.result
  mysql-test/suite/backup/r/backup_commit_backup.result
  mysql-test/suite/backup/r/backup_commit_restore.result
  mysql-test/suite/backup/r/backup_compression.result
  mysql-test/suite/backup/r/backup_concurrent.result
  mysql-test/suite/backup/r/backup_db_grants.result
  mysql-test/suite/backup/r/backup_ddl_blocker.result
  mysql-test/suite/backup/r/backup_errors.result
  mysql-test/suite/backup/r/backup_fkey.result
  mysql-test/suite/backup/r/backup_lock_myisam.result
  mysql-test/suite/backup/r/backup_logs.result
  mysql-test/suite/backup/r/backup_logs_output.result
  mysql-test/suite/backup/r/backup_no_be.result
  mysql-test/suite/backup/r/backup_no_data.result
  mysql-test/suite/backup/r/backup_nodata_driver.result
  mysql-test/suite/backup/r/backup_security.result
  mysql-test/suite/backup/r/backup_snapshot.result
  mysql-test/suite/backup/r/backup_timeout.result
  mysql-test/suite/backup/t/backup.test
  mysql-test/suite/backup/t/backup_backupdir.test
  mysql-test/suite/backup/t/backup_commit_backup.test
  mysql-test/suite/backup/t/backup_commit_restore.test
  mysql-test/suite/backup/t/backup_compression.test
  mysql-test/suite/backup/t/backup_concurrent.test
  mysql-test/suite/backup/t/backup_db_grants.test
  mysql-test/suite/backup/t/backup_ddl_blocker.test
  mysql-test/suite/backup/t/backup_errors.test
  mysql-test/suite/backup/t/backup_fkey.test
  mysql-test/suite/backup/t/backup_lock_myisam.test
  mysql-test/suite/backup/t/backup_logs.test
  mysql-test/suite/backup/t/backup_logs_output.test
  mysql-test/suite/backup/t/backup_no_be.test
  mysql-test/suite/backup/t/backup_no_data.test
  mysql-test/suite/backup/t/backup_nodata_driver.test
  mysql-test/suite/backup/t/backup_security.test
  mysql-test/suite/backup/t/backup_snapshot.test
  mysql-test/suite/backup/t/backup_timeout.test
  mysql-test/suite/backup/t/disabled.def
  mysql-test/suite/backup_engines/include/backup_ptr_commit.inc
  mysql-test/suite/backup_engines/include/backup_ptr_objects.inc
  mysql-test/suite/backup_engines/r/backup_online_testing.result
  mysql-test/suite/backup_engines/r/backup_ptr_commit_mixed.result
  mysql-test/suite/backup_engines/r/backup_ptr_commit_row.result
  mysql-test/suite/backup_engines/r/backup_ptr_commit_stmt.result
  mysql-test/suite/backup_engines/r/backup_ptr_objects_mixed.result
  mysql-test/suite/backup_engines/r/backup_ptr_objects_row.result
  mysql-test/suite/backup_engines/r/backup_ptr_objects_stmt.result
  mysql-test/suite/backup_engines/t/backup_online_testing.test
  mysql-test/suite/falcon/r/falcon_bug_30124.result
  mysql-test/suite/falcon/t/disabled.def
  mysql-test/suite/falcon/t/falcon_bug_30124.test
  mysql-test/t/disabled.def
  mysql-test/t/implicit_commit.test
  sql/backup/backup_info.cc
  sql/backup/backup_info.h
  sql/backup/backup_kernel.h
  sql/backup/be_snapshot.cc
  sql/backup/be_thread.cc
  sql/backup/data_backup.cc
  sql/backup/image_info.cc
  sql/backup/image_info.h
  sql/backup/kernel.cc
  sql/backup/logger.h
  sql/backup/restore_info.h
  sql/backup/stream.h
  sql/backup/stream_v1.c
  sql/lex.h
  sql/log.cc
  sql/log.h
  sql/log_event.cc
  sql/mysqld.cc
  sql/rpl_constants.h
  sql/set_var.cc
  sql/share/errmsg.txt
  sql/si_logs.cc
  sql/si_logs.h
  sql/si_objects.cc
  sql/si_objects.h
  sql/sql_lex.cc
  sql/sql_lex.h
  sql/sql_parse.cc
  sql/sql_repl.cc
  sql/sql_yacc.yy
  storage/csv/ha_tina.cc
  storage/csv/ha_tina.h
  storage/falcon/BlobReference.cpp
  storage/falcon/Cache.cpp
  storage/falcon/Cache.h
  storage/falcon/CollationCaseless.cpp
  storage/falcon/Database.cpp
  storage/falcon/DateTime.cpp
  storage/falcon/Dbb.cpp
  storage/falcon/Dbb.h
  storage/falcon/DeferredIndex.cpp
  storage/falcon/DeferredIndexWalker.cpp
  storage/falcon/EditString.cpp
  storage/falcon/EncodedDataStream.cpp
  storage/falcon/Filter.cpp
  storage/falcon/FilterSet.cpp
  storage/falcon/FsbSort.cpp
  storage/falcon/IO.cpp
  storage/falcon/Index.cpp
  storage/falcon/IndexRootPage.cpp
  storage/falcon/Log.h
  storage/falcon/MemMgr.cpp
  storage/falcon/MemMgr.h
  storage/falcon/MemoryManager.h
  storage/falcon/Record.cpp
  storage/falcon/Record.h
  storage/falcon/RecordScavenge.cpp
  storage/falcon/RecordVersion.cpp
  storage/falcon/RecordVersion.h
  storage/falcon/RecoveryObjects.cpp
  storage/falcon/RecoveryObjects.h
  storage/falcon/SRLUpdateIndex.cpp
  storage/falcon/SRLUpdateRecords.cpp
  storage/falcon/SerialLog.cpp
  storage/falcon/SerialLog.h
  storage/falcon/SerialLogControl.cpp
  storage/falcon/SerialLogFile.cpp
  storage/falcon/SerialLogRecord.cpp
  storage/falcon/SerialLogRecord.h
  storage/falcon/Serialize.cpp
  storage/falcon/StorageHandler.cpp
  storage/falcon/StorageTableShare.cpp
  storage/falcon/StorageTableShare.h
  storage/falcon/StorageVersion.h
  storage/falcon/TableSpaceManager.cpp
  storage/falcon/TableSpaceManager.h
  storage/falcon/Transaction.cpp
  storage/falcon/ha_falcon.cpp
  storage/falcon/ha_falcon.h
  storage/falcon/plug.in
  mysql-test/suite/falcon/r/falcon_bug_28095.result
  mysql-test/suite/falcon/t/falcon_bug_28095.test

=== modified file 'client/mysqltest.c'
--- a/client/mysqltest.c	2008-10-20 09:16:47 +0000
+++ b/client/mysqltest.c	2008-11-03 17:51:36 +0000
@@ -279,6 +279,7 @@ enum enum_commands {
   Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES,
   Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR, Q_LIST_FILES,
   Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE,
+  Q_SEND_SHUTDOWN, Q_SHUTDOWN_SERVER,
 
   Q_UNKNOWN,			       /* Unknown command.   */
   Q_COMMENT,			       /* Comments, ignored. */
@@ -370,6 +371,8 @@ const char *command_names[]=
   "list_files",
   "list_files_write_file",
   "list_files_append_file",
+  "send_shutdown",
+  "shutdown_server",
 
   0
 };
@@ -3855,6 +3858,145 @@ void do_set_charset(struct st_command *c
 }
 
 
+/*
+  Run query and return one field in the result set from the
+  first row and <column>
+*/
+
+int query_get_string(MYSQL* mysql, const char* query,
+                     int column, DYNAMIC_STRING* ds)
+{
+  MYSQL_RES *res= NULL;
+  MYSQL_ROW row;
+
+  if (mysql_query(mysql, query))
+    die("'%s' failed: %d %s", query,
+        mysql_errno(mysql), mysql_error(mysql));
+  if ((res= mysql_store_result(mysql)) == NULL)
+    die("Failed to store result: %d %s",
+        mysql_errno(mysql), mysql_error(mysql));
+
+  if ((row= mysql_fetch_row(res)) == NULL)
+  {
+    mysql_free_result(res);
+    ds= 0;
+    return 1;
+  }
+  init_dynamic_string(ds, (row[column] ? row[column] : "NULL"), ~0, 32);
+  mysql_free_result(res);
+  return 0;
+}
+
+
+static int my_kill(int pid, int sig)
+{
+#ifdef __WIN__
+  HANDLE proc;
+  if ((proc= OpenProcess(PROCESS_TERMINATE, FALSE, pid)) == NULL)
+    return -1;
+  if (sig == 0)
+  {
+    CloseHandle(proc);
+    return 0;
+  }
+  (void)TerminateProcess(proc, 201);
+  CloseHandle(proc);
+  return 1;
+#else
+  return kill(pid, sig);
+#endif
+}
+
+
+
+/*
+  Shutdown the server of current connection and
+  make sure it goes away within <timeout> seconds
+
+  NOTE! Currently only works with local server
+
+  SYNOPSIS
+  do_shutdown_server()
+  command  called command
+
+  DESCRIPTION
+  shutdown [<timeout>]
+
+*/
+
+void do_shutdown_server(struct st_command *command)
+{
+  int timeout=60, pid;
+  DYNAMIC_STRING ds_pidfile_name;
+  MYSQL* mysql = &cur_con->mysql;
+  static DYNAMIC_STRING ds_timeout;
+  const struct command_arg shutdown_args[] = {
+    {"timeout", ARG_STRING, FALSE, &ds_timeout, "Timeout before killing server"}
+  };
+  DBUG_ENTER("do_shutdown_server");
+
+  check_command_args(command, command->first_argument, shutdown_args,
+                     sizeof(shutdown_args)/sizeof(struct command_arg),
+                     ' ');
+
+  if (ds_timeout.length)
+  {
+    timeout= atoi(ds_timeout.str);
+    if (timeout == 0)
+      die("Illegal argument for timeout: '%s'", ds_timeout.str);
+  }
+  dynstr_free(&ds_timeout);
+
+  /* Get the servers pid_file name and use it to read pid */
+  if (query_get_string(mysql, "SHOW VARIABLES LIKE 'pid_file'", 1,
+                       &ds_pidfile_name))
+    die("Failed to get pid_file from server");
+
+  /* Read the pid from the file */
+  {
+    int fd;
+    char buff[32];
+
+    if ((fd= my_open(ds_pidfile_name.str, O_RDONLY, MYF(0))) < 0)
+      die("Failed to open file '%s'", ds_pidfile_name.str);
+    dynstr_free(&ds_pidfile_name);
+
+    if (my_read(fd, (uchar*)&buff,
+                sizeof(buff), MYF(0)) <= 0){
+      my_close(fd, MYF(0));
+      die("pid file was empty");
+    }
+    my_close(fd, MYF(0));
+
+    pid= atoi(buff);
+    if (pid == 0)
+      die("Pidfile didn't contain a valid number");
+  }
+  DBUG_PRINT("info", ("Got pid %d", pid));
+
+  /* Tell server to shutdown if timeout > 0*/
+  if (timeout && mysql_shutdown(mysql, SHUTDOWN_DEFAULT))
+    die("mysql_shutdown failed");
+
+  /* Check that server dies */
+  while(timeout--){
+    if (my_kill(0, pid) < 0){
+      DBUG_PRINT("info", ("Process %d does not exist anymore", pid));
+      break;
+    }
+    DBUG_PRINT("info", ("Sleeping, timeout: %d", timeout));
+    my_sleep(1000000L);
+  }
+
+  /* Kill the server */
+  DBUG_PRINT("info", ("Killing server, pid: %d", pid));
+  (void)my_kill(9, pid);
+
+  DBUG_VOID_RETURN;
+
+}
+
+
 #if MYSQL_VERSION_ID >= 50000
 /* List of error names to error codes, available from 5.0 */
 typedef struct
@@ -7440,6 +7582,14 @@ int main(int argc, char **argv)
       case Q_PING:
 	(void) mysql_ping(&cur_con->mysql);
 	break;
+      case Q_SEND_SHUTDOWN:
+        handle_command_error(command,
+                             mysql_shutdown(&cur_con->mysql,
+                                            SHUTDOWN_DEFAULT));
+        break;
+      case Q_SHUTDOWN_SERVER:
+        do_shutdown_server(command);
+        break;
       case Q_EXEC:
 	do_exec(command);
 	command_executed++;

=== modified file 'configure.in'
--- a/configure.in	2008-11-11 14:46:00 +0000
+++ b/configure.in	2008-11-13 14:22:12 +0000
@@ -1800,9 +1800,6 @@ case "$with_atomic_ops" in
    *) AC_MSG_ERROR(["$with_atomic_ops" is not a valid value for --with-atomic-ops]) ;;
 esac
 
-# Check if we have the atomic_* functions on Solaris
-AC_CHECK_FUNC(atomic_cas_32, AC_DEFINE([HAVE_SOLARIS_ATOMIC], [1], [Define to 1 if Solaris support atomic functions.]))
-
 # Force static compilation to avoid linking problems/get more speed
 AC_ARG_WITH(mysqld-ldflags,
     [  --with-mysqld-ldflags   Extra linking arguments for mysqld],

=== modified file 'include/my_base.h'
--- a/include/my_base.h	2008-10-20 09:16:47 +0000
+++ b/include/my_base.h	2008-10-28 14:17:05 +0000
@@ -208,7 +208,8 @@ enum ha_extra_function {
   HA_EXTRA_ORDERBY_LIMIT,
   HA_EXTRA_NO_ORDERBY_LIMIT,
   /* Inform handler we will force a close as part of flush */
-  HA_EXTRA_PREPARE_FOR_FORCED_CLOSE
+  HA_EXTRA_PREPARE_FOR_FORCED_CLOSE,
+  HA_EXTRA_ALLOW_LOG_DELETE
 };
 
 /* Compatible option, to be deleted in 6.0 */

=== added file 'mysql-test/include/restart_mysqld.inc'
--- a/mysql-test/include/restart_mysqld.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/restart_mysqld.inc	2008-11-13 14:55:42 +0000
@@ -0,0 +1,28 @@
+#
+# Write file to make mysql-test-run.pl expect the "crash", but don't start
+# it until it's told to
+--write_file $MYSQLTEST_VARDIR/tmp/master0.expect
+wait
+EOF
+
+# Send shutdown to the connected server and give
+# it 30 seconds to die before zapping it.
+shutdown_server 30;
+
+# Check server is gone
+--source include/wait_until_disconnected.inc
+
+# Write file to make mysql-test-run.pl start up the server again
+--append_file $MYSQLTEST_VARDIR/tmp/master0.expect
+restart
+EOF
+
+# Turn on reconnect
+--enable_reconnect
+
+# Call script that will poll the server waiting for it to be back online again
+--source include/wait_until_connected_again.inc
+
+# Turn off reconnect again
+--disable_reconnect
+

=== modified file 'mysql-test/include/wait_until_connected_again.inc'
--- a/mysql-test/include/wait_until_connected_again.inc	2008-02-06 17:04:06 +0000
+++ b/mysql-test/include/wait_until_connected_again.inc	2008-11-13 14:55:42 +0000
@@ -4,11 +4,14 @@
 # You should have done --enable_reconnect first
 --disable_result_log
 --disable_query_log
-let $counter= 5000;
-let $mysql_errno= 1;
+let $counter= 600;
+let $mysql_errno= 9999;
 while ($mysql_errno)
 {
-  --error 0,2002,2003,2006,1053
+  # Strangely enough, the server might return "Too many connections"
+  # while being shutdown, thus 1040 is an "allowed" error
+  # See BUG#36228
+  --error 0,1040,1053,2002,2003,2006,2013
   show status;
 
   dec $counter;
@@ -16,7 +19,7 @@ while ($mysql_errno)
   {
     --die Server failed to restart
   }
-  --sleep 0.1
+  --real_sleep 0.1
 }
 --enable_query_log
 --enable_result_log

=== added file 'mysql-test/include/wait_until_disconnected.inc'
--- a/mysql-test/include/wait_until_disconnected.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/wait_until_disconnected.inc	2008-11-03 17:51:36 +0000
@@ -0,0 +1,21 @@
+#
+# Include this script to wait until the connection to the
+# server has been dropped
+--disable_result_log
+--disable_query_log
+let $counter= 500;
+let $mysql_errno= 9999;
+while (!$mysql_errno)
+{
+  --error 0,1053,2002,2006
+  show status;
+
+  dec $counter;
+  if (!$counter)
+  {
+    --die Server failed to dissapear
+  }
+  --sleep 0.1
+}
+--enable_query_log
+--enable_result_log

=== modified file 'mysql-test/lib/mtr_report.pl'
--- a/mysql-test/lib/mtr_report.pl	2008-10-27 13:06:21 +0000
+++ b/mysql-test/lib/mtr_report.pl	2008-11-21 15:02:34 +0000
@@ -352,6 +352,19 @@ sub mtr_report_stats ($) {
 		  /Restore:/ or /was skipped because the user does not exist/
 		) or
                 
+		# backup_logs_output has warning because --log-backup-output option does 
+    # not have argument
+		($testname eq 'backup.backup_logs_output') and
+		(
+		  /Although a path was specified for the/
+		) or
+                
+		# backup_nodata_driver intentionally provokes an error in opening a MERGE table
+		($testname eq 'backup.backup_nodata_driver') and
+		(
+		  /Restore: Open and lock tables failed in RESTORE/
+		) or
+                
 		# The tablespace test triggers error below on purpose
 		($testname eq 'backup.backup_tablespace') and
 		(

=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl	2008-10-23 16:29:52 +0000
+++ b/mysql-test/mysql-test-run.pl	2008-11-12 17:42:23 +0000
@@ -133,7 +133,7 @@ our $default_vardir;
 
 our $opt_usage;
 our $opt_suites;
-our $opt_suites_default= "main,backup,binlog,rpl,rpl_ndb,ndb"; # Default suites to run
+our $opt_suites_default= "main,backup,backup_engines,binlog,rpl,rpl_ndb,ndb"; # Default suites to run
 our $opt_script_debug= 0;  # Script debugging, enable with --script-debug
 our $opt_verbose= 0;  # Verbose output, enable with --verbose
 

=== modified file 'mysql-test/r/implicit_commit.result'
--- a/mysql-test/r/implicit_commit.result	2008-07-26 16:38:20 +0000
+++ b/mysql-test/r/implicit_commit.result	2008-11-20 14:03:27 +0000
@@ -1035,7 +1035,7 @@ YES
 # SQLCOM_RESTORE
 #
 INSERT INTO db1.trans (a) VALUES (1);
-restore from 'backup_db1.ba';
+restore from 'backup_db1.ba' overwrite;
 CALL db1.test_if_commit();
 IMPLICIT COMMIT
 YES

=== modified file 'mysql-test/suite/backup/r/backup.result'
--- a/mysql-test/suite/backup/r/backup.result	2008-11-28 21:35:11 +0000
+++ b/mysql-test/suite/backup/r/backup.result	2008-12-04 23:14:30 +0000
@@ -562,7 +562,7 @@ id	ccode
 2	bb
 4	dd
 do restore
-RESTORE FROM 'bup_delete.bak';
+RESTORE FROM 'bup_delete.bak' OVERWRITE;
 backup_id
 #
 show the data
@@ -597,7 +597,7 @@ BACKUP DATABASE bup_default TO 'bup_defa
 backup_id
 #
 Restore the database.
-RESTORE FROM 'bup_default_timestamp.bak';
+RESTORE FROM 'bup_default_timestamp.bak' OVERWRITE;
 backup_id
 #
 Show data after restore (timestamp should be same as above).

=== modified file 'mysql-test/suite/backup/r/backup_backupdir.result'
--- a/mysql-test/suite/backup/r/backup_backupdir.result	2008-10-24 15:37:11 +0000
+++ b/mysql-test/suite/backup/r/backup_backupdir.result	2008-11-17 09:57:51 +0000
@@ -15,7 +15,7 @@ backup_id
 Ensure backup image file went to the correct location
 /backup/bup_backupdir.bak
 Perform restore
-RESTORE FROM 'bup_backupdir1.bak';
+RESTORE FROM 'bup_backupdir1.bak' OVERWRITE;
 backup_id
 #
 Now do the backup and restore by specifying a path.
@@ -25,7 +25,7 @@ backup_id
 #
 Ensure backup image file went to the correct location
 Perform restore
-RESTORE FROM '../bup_backupdir2.bak';
+RESTORE FROM '../bup_backupdir2.bak' OVERWRITE;
 backup_id
 #
 Perform backup

=== modified file 'mysql-test/suite/backup/r/backup_commit_backup.result'
--- a/mysql-test/suite/backup/r/backup_commit_backup.result	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_commit_backup.result	2008-11-17 09:57:51 +0000
@@ -299,7 +299,7 @@ SELECT release_lock("sync");
 release_lock("sync")
 1
 Checking contents of the backup image
-RESTORE FROM 'db1.bak';
+RESTORE FROM 'db1.bak' OVERWRITE;
 backup_id
 #
 SELECT * FROM db1.t1;

=== removed file 'mysql-test/suite/backup/r/backup_commit_blocker.result'
--- a/mysql-test/suite/backup/r/backup_commit_blocker.result	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_commit_blocker.result	1970-01-01 00:00:00 +0000
@@ -1,469 +0,0 @@
-SET DEBUG_SYNC= 'RESET';
-DROP DATABASE IF EXISTS bup_commit_blocker;
-CREATE DATABASE bup_commit_blocker;
-
-Starting Test 1
-
-con1: Creating tables
-CREATE TABLE bup_commit_blocker.t1 (col_a CHAR(40)) ENGINE=INNODB;
-CREATE TABLE bup_commit_blocker.t2 (col_a CHAR(40)) ENGINE=INNODB;
-CREATE TABLE bup_commit_blocker.t3 (col_a CHAR(40)) ENGINE=INNODB;
-con1: Loading data
-INSERT INTO bup_commit_blocker.t1 VALUES ("01 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("02 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("03 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("04 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("05 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("01 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("02 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("03 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("04 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("05 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("01 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("02 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("03 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("04 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("05 Some data to test");
-con1: Show that the new data doesn't exist before backup.
-SELECT * FROM bup_commit_blocker.t1;
-col_a
-01 Some data to test
-02 Some data to test
-03 Some data to test
-04 Some data to test
-05 Some data to test
-SELECT * FROM bup_commit_blocker.t2;
-col_a
-01 Some data to test
-02 Some data to test
-03 Some data to test
-04 Some data to test
-05 Some data to test
-SELECT * FROM bup_commit_blocker.t3;
-col_a
-01 Some data to test
-02 Some data to test
-03 Some data to test
-04 Some data to test
-05 Some data to test
-con2: Get a transaction going and stop in the middle
-Assumption (a): TRX in progress is not included in backup
-BEGIN;
-UPDATE bup_commit_blocker.t1 SET col_a = "con2: CHANGED" WHERE col_a LIKE '01%';
-con3: Start a transaction and send commit after lock is taken
-Assumption (b): TRX in commit is included in backup
-BEGIN;
-INSERT INTO bup_commit_blocker.t2 VALUES ("con3: 04 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("con3: 05 Some data to test");
-con1: Activate synchronization points for BACKUP.
-SET DEBUG_SYNC= 'before_commit_block SIGNAL bup_commit_block
-                 WAIT_FOR bup_go_read_lock';
-SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL bup_read_lock';
-SET DEBUG_SYNC= 'before_backup_data_lock WAIT_FOR commit_done';
-SET DEBUG_SYNC= 'before_backup_unblock_commit SIGNAL bup_read_locked
-                 WAIT_FOR finish';
-con1: Backing up database -- will block with lock
-BACKUP DATABASE bup_commit_blocker TO "bup_commit_blocker.bak";
-con5: Wait for BACKUP to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR bup_commit_block';
-con3: Activate synchronization points for COMMIT.
-SET DEBUG_SYNC= 'within_ha_commit_trans SIGNAL commit_read_locked
-                 WAIT_FOR commit_go_done';
-SET DEBUG_SYNC= 'after_commit SIGNAL commit_done WAIT_FOR finish';
-con3: Starting commit -- will block on sync point
-COMMIT;
-con5: Wait for COMMIT to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR commit_read_locked';
-con5: Let BACKUP run until the next sync point.
-SET DEBUG_SYNC= 'now SIGNAL bup_go_read_lock WAIT_FOR bup_read_lock';
-con5: Let COMMIT continue until end of statement.
-con5: The completed COMMIT implicitly wakes BACKUP.
-con5: So wait for BACKUP to reach the next synchronization point.
-SET DEBUG_SYNC= 'now SIGNAL commit_go_done WAIT_FOR bup_read_locked';
-con4: Activate synchronization point for BEGIN.
-SET DEBUG_SYNC= 'before_begin_trans SIGNAL begin_starting
-                 WAIT_FOR finish';
-con4: Starting begin -- will block on sync point
-Assumption (c): TRX not started is not included in backup
-BEGIN;
-con5: Wait for BEGIN to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR begin_starting';
-con5: Sending finish signal to wake them all.
-SET DEBUG_SYNC= 'now SIGNAL finish';
-con2: Completing transaction
-DELETE FROM bup_commit_blocker.t1 WHERE col_a LIKE '02%';
-COMMIT;
-con3: Fetch COMMIT result
-con4: Fetch BEGIN result and completing transaction
-UPDATE bup_commit_blocker.t3 SET col_a = "con4: 05 CHANGED" WHERE col_a LIKE '05%';
-UPDATE bup_commit_blocker.t3 SET col_a = "con4: 06 CHANGED" WHERE col_a LIKE '06%';
-COMMIT;
-con1: Fetch BACKUP result
-backup_id
-#
-con1: Showing data after updates and backup
-SELECT * FROM bup_commit_blocker.t1;
-col_a
-con2: CHANGED
-03 Some data to test
-04 Some data to test
-05 Some data to test
-SELECT * FROM bup_commit_blocker.t2;
-col_a
-01 Some data to test
-02 Some data to test
-03 Some data to test
-04 Some data to test
-05 Some data to test
-con3: 04 Some data to test
-con3: 05 Some data to test
-SELECT * FROM bup_commit_blocker.t3;
-col_a
-01 Some data to test
-02 Some data to test
-03 Some data to test
-04 Some data to test
-con4: 05 CHANGED
-con1: Dropping the database
-DROP TABLE bup_commit_blocker.t1;
-DROP TABLE bup_commit_blocker.t2;
-DROP TABLE bup_commit_blocker.t3;
-con1: Restoring the database
-RESTORE FROM "bup_commit_blocker.bak";
-backup_id
-#
-con1: Showing the data (no new data should be here).
-SELECT * FROM bup_commit_blocker.t1;
-col_a
-01 Some data to test
-02 Some data to test
-03 Some data to test
-04 Some data to test
-05 Some data to test
-SELECT * FROM bup_commit_blocker.t2;
-col_a
-01 Some data to test
-02 Some data to test
-03 Some data to test
-04 Some data to test
-05 Some data to test
-con3: 04 Some data to test
-con3: 05 Some data to test
-SELECT * FROM bup_commit_blocker.t3;
-col_a
-01 Some data to test
-02 Some data to test
-03 Some data to test
-04 Some data to test
-05 Some data to test
-
-Verifying test 1 results:
-
-T1 should not have the changes after backup - count(*) = 0
-SELECT count(*) FROM bup_commit_blocker.t1 WHERE col_a like 'con2%';
-count(*)
-0
-T2 should have the changes after backup - count(*) = 2
-SELECT count(*) FROM bup_commit_blocker.t2 WHERE col_a like 'con3%';
-count(*)
-2
-T3 should not have the changes after backup - count(*) = 0
-SELECT count(*) FROM bup_commit_blocker.t3 WHERE col_a like 'con4%';
-count(*)
-0
-con1: Cleanup
-DROP DATABASE bup_commit_blocker;
-SET DEBUG_SYNC= 'RESET';
-
-Starting Test 2
-
-CREATE DATABASE bup_commit_blocker;
-con1: Creating tables
-CREATE TABLE bup_commit_blocker.t5 (col_a int) ENGINE=MEMORY;
-con1: Loading data
-INSERT INTO bup_commit_blocker.t5 VALUES (10), (20), (30), (40), (50);
-con1: Show that the new data doesn't exist before backup.
-SELECT * FROM bup_commit_blocker.t5;
-col_a
-10
-20
-30
-40
-50
-con1: Activate synchronization point for BACKUP.
-SET DEBUG_SYNC= 'before_backup_data_unlock SIGNAL bup_data_unlock
-                 WAIT_FOR finish';
-con1: Backing up database -- will block with lock
-BACKUP DATABASE bup_commit_blocker TO "bup_commit_blocker.bak";
-con5: Wait for BACKUP to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR bup_data_unlock';
-con7: Show that the statement in progress has executed before backup.
-SELECT * FROM bup_commit_blocker.t5;
-col_a
-10
-20
-30
-40
-50
-con7: Activate synchronization point for UPDATE.
-SET DEBUG_SYNC= 'wait_if_global_read_lock SIGNAL upd_read_lock';
-con7: Starting non-trx about to start
-Assumption (e): non-TRX not started is not included in backup
-UPDATE bup_commit_blocker.t5 SET col_a = 333 WHERE col_a = 30;
-con5: Wait for UPDATE to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR upd_read_lock';
-con5: Sending finish signal to wake them all.
-SET DEBUG_SYNC= 'now SIGNAL finish';
-con7: Fetch UPDATE result
-con1: Fetch BACKUP result
-backup_id
-#
-con1: Showing data after updates and backup
-SELECT * FROM bup_commit_blocker.t5;
-col_a
-10
-20
-333
-40
-50
-con1: Dropping the database
-DROP TABLE bup_commit_blocker.t5;
-con1: Restoring the database
-RESTORE FROM "bup_commit_blocker.bak";
-backup_id
-#
-con1: Showing the data (no new data should be here).
-SELECT * FROM bup_commit_blocker.t5;
-col_a
-10
-20
-30
-40
-50
-
-Verifying test 2 results:
-
-T5 should not have the changes after backup - count(*) = 0
-SELECT count(*) FROM bup_commit_blocker.t5 WHERE col_a = 333;
-count(*)
-0
-con1: Cleanup
-DROP DATABASE bup_commit_blocker;
-SET DEBUG_SYNC= 'RESET';
-
-Starting Test 3
-
-CREATE DATABASE bup_commit_blocker;
-con1: Creating tables
-CREATE TABLE bup_commit_blocker.t1 (col_a CHAR(40)) ENGINE=INNODB;
-CREATE TABLE bup_commit_blocker.t2 (col_a CHAR(40)) ENGINE=INNODB;
-CREATE TABLE bup_commit_blocker.t3 (col_a CHAR(40)) ENGINE=INNODB;
-CREATE TABLE bup_commit_blocker.t5 (col_a int) ENGINE=MEMORY;
-con1: Loading data
-INSERT INTO bup_commit_blocker.t1 VALUES ("01 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("02 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("03 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("04 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("05 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("01 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("02 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("03 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("04 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("05 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("01 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("02 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("03 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("04 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("05 Some data to test");
-INSERT INTO bup_commit_blocker.t5 VALUES (10), (20), (30), (40), (50);
-con1: Show that the new data doesn't exist before backup.
-SELECT * FROM bup_commit_blocker.t1;
-col_a
-01 Some data to test
-02 Some data to test
-03 Some data to test
-04 Some data to test
-05 Some data to test
-SELECT * FROM bup_commit_blocker.t2;
-col_a
-01 Some data to test
-02 Some data to test
-03 Some data to test
-04 Some data to test
-05 Some data to test
-SELECT * FROM bup_commit_blocker.t3;
-col_a
-01 Some data to test
-02 Some data to test
-03 Some data to test
-04 Some data to test
-05 Some data to test
-SELECT * FROM bup_commit_blocker.t5;
-col_a
-10
-20
-30
-40
-50
-con2: Get a transaction going and stop in the middle
-Assumption (a): TRX in progress is not included in backup
-BEGIN;
-UPDATE bup_commit_blocker.t1 SET col_a = "con2: CHANGED" WHERE col_a LIKE '01%';
-con3: Start a transaction and send commit after lock is taken
-Assumption (b): TRX in commit is included in backup
-BEGIN;
-INSERT INTO bup_commit_blocker.t2 VALUES ("con3: 04 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("con3: 05 Some data to test");
-con1: Activate synchronization points for BACKUP.
-SET DEBUG_SYNC= 'before_commit_block SIGNAL bup_commit_block
-                 WAIT_FOR bup_go_read_lock';
-SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL bup_read_lock';
-SET DEBUG_SYNC= 'before_backup_data_lock WAIT_FOR commit_done';
-SET DEBUG_SYNC= 'before_backup_unblock_commit SIGNAL bup_read_locked
-                 WAIT_FOR finish';
-con1: Backing up database -- will block with lock
-BACKUP DATABASE bup_commit_blocker TO "bup_commit_blocker.bak";
-con5: Wait for BACKUP to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR bup_commit_block';
-con3: Activate synchronization points for COMMIT.
-SET DEBUG_SYNC= 'within_ha_commit_trans SIGNAL commit_read_locked
-                 WAIT_FOR commit_go_done';
-SET DEBUG_SYNC= 'after_commit SIGNAL commit_done WAIT_FOR finish';
-con3: Starting commit -- will block on sync point
-COMMIT;
-con5: Wait for COMMIT to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR commit_read_locked';
-con5: Let BACKUP run until the next sync point.
-SET DEBUG_SYNC= 'now SIGNAL bup_go_read_lock WAIT_FOR bup_read_lock';
-con5: Let COMMIT continue until the sync point at its end.
-con5: The completed COMMIT implicitly wakes BACKUP.
-con5: So wait for BACKUP to reach the next synchronization point.
-SET DEBUG_SYNC= 'now SIGNAL commit_go_done WAIT_FOR bup_read_locked';
-con4: Activate synchronization point for BEGIN.
-SET DEBUG_SYNC= 'before_begin_trans SIGNAL begin_starting
-                 WAIT_FOR finish';
-con4: Starting begin -- will block with lock
-Assumption (c): TRX not started is not included in backup
-BEGIN;
-con5: Wait for BEGIN to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR begin_starting';
-con7: Show that the statement in progress has executed before backup.
-SELECT * FROM bup_commit_blocker.t5;
-col_a
-10
-20
-30
-40
-50
-con7: Activate synchronization point for DELETE.
-SET DEBUG_SYNC= 'wait_if_global_read_lock SIGNAL del_read_lock';
-con7: Starting non-trx about to start -- will block with lock
-Assumption (e): non-TRX not started is not included in backup
-DELETE FROM bup_commit_blocker.t5 WHERE col_a = 50;
-con5: Wait for DELETE to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR del_read_lock';
-con5: Sending finish signal to wake them all.
-SET DEBUG_SYNC= 'now SIGNAL finish';
-con2: Completing transaction
-DELETE FROM bup_commit_blocker.t2 WHERE col_a LIKE '02%';
-COMMIT;
-con3: Fetch COMMIT result
-con4: Fetch BEGIN result and completing transaction
-UPDATE bup_commit_blocker.t3 SET col_a = "con4: 05 CHANGED" WHERE col_a LIKE '05%';
-UPDATE bup_commit_blocker.t3 SET col_a = "con4: 06 CHANGED" WHERE col_a LIKE '06%';
-COMMIT;
-con7: Fetch DELETE result
-con1: Fetch BACKUP result
-backup_id
-#
-con1: Showing data after updates and backup
-SELECT * FROM bup_commit_blocker.t1;
-col_a
-con2: CHANGED
-02 Some data to test
-03 Some data to test
-04 Some data to test
-05 Some data to test
-SELECT * FROM bup_commit_blocker.t2;
-col_a
-01 Some data to test
-03 Some data to test
-04 Some data to test
-05 Some data to test
-con3: 04 Some data to test
-con3: 05 Some data to test
-SELECT * FROM bup_commit_blocker.t3;
-col_a
-01 Some data to test
-02 Some data to test
-03 Some data to test
-04 Some data to test
-con4: 05 CHANGED
-SELECT * FROM bup_commit_blocker.t5;
-col_a
-10
-20
-30
-40
-con1: Dropping the database
-DROP TABLE bup_commit_blocker.t1;
-DROP TABLE bup_commit_blocker.t2;
-DROP TABLE bup_commit_blocker.t3;
-DROP TABLE bup_commit_blocker.t5;
-con1: Restoring the database
-RESTORE FROM "bup_commit_blocker.bak";
-backup_id
-#
-con1: Showing the data (no new data should be here).
-SELECT * FROM bup_commit_blocker.t1;
-col_a
-01 Some data to test
-02 Some data to test
-03 Some data to test
-04 Some data to test
-05 Some data to test
-SELECT * FROM bup_commit_blocker.t2;
-col_a
-01 Some data to test
-02 Some data to test
-03 Some data to test
-04 Some data to test
-05 Some data to test
-con3: 04 Some data to test
-con3: 05 Some data to test
-SELECT * FROM bup_commit_blocker.t3;
-col_a
-01 Some data to test
-02 Some data to test
-03 Some data to test
-04 Some data to test
-05 Some data to test
-SELECT * FROM bup_commit_blocker.t5;
-col_a
-10
-20
-30
-40
-50
-
-Verifying test 3 results:
-
-T1 should not have the changes after backup - count(*) = 0
-SELECT count(*) FROM bup_commit_blocker.t1 WHERE col_a like 'con2%';
-count(*)
-0
-T2 should have the changes after backup - count(*) = 2
-SELECT count(*) FROM bup_commit_blocker.t2 WHERE col_a like 'con3%';
-count(*)
-2
-T3 should not have the changes after backup - count(*) = 0
-SELECT count(*) FROM bup_commit_blocker.t3 WHERE col_a like 'con4%';
-count(*)
-0
-T5 should not have the changes after backup - count(*) = 1
-SELECT count(*) FROM bup_commit_blocker.t5 WHERE col_a >= 50;
-count(*)
-1
-con1: Cleanup
-DROP DATABASE bup_commit_blocker;
-SET DEBUG_SYNC= 'RESET';

=== modified file 'mysql-test/suite/backup/r/backup_commit_restore.result'
--- a/mysql-test/suite/backup/r/backup_commit_restore.result	2008-10-23 08:13:54 +0000
+++ b/mysql-test/suite/backup/r/backup_commit_restore.result	2008-11-17 09:57:51 +0000
@@ -6,7 +6,7 @@ INSERT INTO t1 VALUES ('a1');
 BACKUP DATABASE commit_test TO '81';
 backup_id
 #
-RESTORE FROM '81';
+RESTORE FROM '81' OVERWRITE;
 backup_id
 #
 SELECT * FROM t1;
@@ -24,7 +24,7 @@ INSERT INTO t2 VALUES ('a2');
 BACKUP DATABASE commit_test TO '82';
 backup_id
 #
-RESTORE FROM '82';
+RESTORE FROM '82' OVERWRITE;
 backup_id
 #
 SELECT * FROM t1;
@@ -51,7 +51,7 @@ INSERT INTO t3 VALUES ('a3');
 BACKUP DATABASE commit_test TO '83';
 backup_id
 #
-RESTORE FROM '83';
+RESTORE FROM '83' OVERWRITE;
 backup_id
 #
 SELECT * FROM t1;
@@ -89,7 +89,7 @@ INSERT INTO t4 VALUES ('a4');
 BACKUP DATABASE commit_test TO '84';
 backup_id
 #
-RESTORE FROM '84';
+RESTORE FROM '84' OVERWRITE;
 backup_id
 #
 SELECT * FROM t1;
@@ -138,7 +138,7 @@ INSERT INTO t4 VALUES ('a5');
 BACKUP DATABASE commit_test TO '85';
 backup_id
 #
-RESTORE FROM '85';
+RESTORE FROM '85' OVERWRITE;
 backup_id
 #
 SELECT * FROM t1;
@@ -198,7 +198,7 @@ BACKUP DATABASE commit_test TO '86';
 backup_id
 #
 SET @@autocommit=0;
-RESTORE FROM '86';
+RESTORE FROM '86' OVERWRITE;
 backup_id
 #
 DROP TABLE t5;
@@ -265,7 +265,7 @@ BACKUP DATABASE commit_test TO '87';
 backup_id
 #
 SET @@autocommit=1;
-RESTORE FROM '87';
+RESTORE FROM '87' OVERWRITE;
 backup_id
 #
 SELECT * FROM t1;

=== modified file 'mysql-test/suite/backup/r/backup_compression.result'
--- a/mysql-test/suite/backup/r/backup_compression.result	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_compression.result	2008-11-17 09:57:51 +0000
@@ -7,13 +7,13 @@ CREATE TABLE db1.t2(a INT);
 BACKUP DATABASE db1 TO 'db2.bak.gz' WITH COMPRESSION COMPRESSION_ALGORITHM=gzip;
 backup_id
 #
-RESTORE FROM 'db1.bak.gz';
+RESTORE FROM 'db1.bak.gz' OVERWRITE;
 backup_id
 #
 SHOW TABLES FROM db1;
 Tables_in_db1
 t1
-RESTORE FROM 'db2.bak.gz';
+RESTORE FROM 'db2.bak.gz' OVERWRITE;
 backup_id
 #
 SHOW TABLES FROM db1;

=== modified file 'mysql-test/suite/backup/r/backup_concurrent.result'
--- a/mysql-test/suite/backup/r/backup_concurrent.result	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_concurrent.result	2008-11-17 09:57:51 +0000
@@ -49,7 +49,7 @@ Testing starting backup/restore restore 
 ---------------------------------------------------
 Starting restore
 SET DEBUG_SYNC= 'after_backup_start_restore SIGNAL running WAIT_FOR restore';
-RESTORE FROM 'backup1';
+RESTORE FROM 'backup1' OVERWRITE;
 Waiting for restore to get going
 SET DEBUG_SYNC= 'now WAIT_FOR running';
 Starting backup in another connection.  

=== modified file 'mysql-test/suite/backup/r/backup_db_grants.result'
--- a/mysql-test/suite/backup/r/backup_db_grants.result	2008-11-19 16:32:01 +0000
+++ b/mysql-test/suite/backup/r/backup_db_grants.result	2008-12-04 23:14:30 +0000
@@ -66,7 +66,7 @@ GRANT USAGE ON *.* TO 'bup_user3'@'%'
 SHOW GRANTS FOR 'no_user'@'%';
 ERROR 42000: There is no such grant defined for user 'no_user' on host '%'
 Run Restore
-RESTORE FROM 'bup_db_grants.bak';
+RESTORE FROM 'bup_db_grants.bak' OVERWRITE;
 backup_id
 #
 Warnings:
@@ -117,7 +117,7 @@ FLUSH PRIVILEGES;
 CREATE USER 'bup_user1'@'%';
 CREATE USER 'bup_user1'@'nosuchhost';
 Run Restore
-RESTORE FROM 'bup_db_grants.bak';
+RESTORE FROM 'bup_db_grants.bak' OVERWRITE;
 backup_id
 #
 Warnings:
@@ -209,7 +209,7 @@ EXECUTE stmt3;
 Grants for �@@%
 GRANT USAGE ON *.* TO '�@'@'%'
 Run restore.
-RESTORE FROM 'bup_db_grants.bak';
+RESTORE FROM 'bup_db_grants.bak' OVERWRITE;
 backup_id
 #
 FLUSH PRIVILEGES;

=== modified file 'mysql-test/suite/backup/r/backup_ddl_blocker.result'
--- a/mysql-test/suite/backup/r/backup_ddl_blocker.result	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_ddl_blocker.result	2008-11-20 14:07:23 +0000
@@ -112,7 +112,7 @@ con1: Dropping the database tables
 DROP TABLE bup_ddl_blocker.t1, bup_ddl_blocker.t2,
 bup_ddl_blocker.t3, bup_ddl_blocker.t4;
 con1: Restoring the database
-RESTORE FROM "bup_ddl_blocker.bak";
+RESTORE FROM "bup_ddl_blocker.bak" OVERWRITE;
 backup_id
 #
 con1: Showing columns that were backed up
@@ -173,13 +173,13 @@ con1: Activate synchronization points fo
 SET DEBUG_SYNC= 'before_block_ddl SIGNAL bup_blocked WAIT_FOR status_shown';
 SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_started WAIT_FOR status_shown2';
 con1: Restoring database -- will block with lock
-RESTORE FROM "bup_ddl_blocker_orig.bak";
+RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE;
 con6: Wait for con1 to reach its synchronization point.
 SET DEBUG_SYNC= 'now WAIT_FOR bup_blocked';
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "RESTORE FROM%";
 state	info
-debug sync point: before_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak"
+debug sync point: before_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "CREATE TABLE bup_ddl_blocker.t1%";
 state	info
@@ -193,7 +193,7 @@ SET DEBUG_SYNC= 'now SIGNAL status_shown
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "RESTORE FROM%";
 state	info
-debug sync point: after_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak"
+debug sync point: after_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE
 con4: Activate synchronization point for DDL.
 SET DEBUG_SYNC= 'before_check_ddl_blocked SIGNAL con4_started
                  WAIT_FOR status_shown2';
@@ -352,7 +352,7 @@ con1: Dropping the database tables
 DROP TABLE bup_ddl_blocker.t01, bup_ddl_blocker.t2,
 bup_ddl_blocker.t03, bup_ddl_blocker.t4;
 con1: Restoring the database
-RESTORE FROM "bup_ddl_blocker.bak";
+RESTORE FROM "bup_ddl_blocker.bak" OVERWRITE;
 backup_id
 #
 con1: Showing columns that were backed up
@@ -407,13 +407,13 @@ con1: Activate synchronization points fo
 SET DEBUG_SYNC= 'before_block_ddl SIGNAL bup_blocked WAIT_FOR status_shown';
 SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_started WAIT_FOR status_shown2';
 con1: Restoring database -- will block with lock
-RESTORE FROM "bup_ddl_blocker_orig.bak";
+RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE;
 con6: Wait for con1 to reach its synchronization point.
 SET DEBUG_SYNC= 'now WAIT_FOR bup_blocked';
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "RESTORE FROM%";
 state	info
-debug sync point: before_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak"
+debug sync point: before_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "RENAME TABLE bup_ddl_blocker.t1%";
 state	info
@@ -427,7 +427,7 @@ SET DEBUG_SYNC= 'now SIGNAL status_shown
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "RESTORE FROM%";
 state	info
-debug sync point: after_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak"
+debug sync point: after_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE
 con4: Activate synchronization point for DDL.
 SET DEBUG_SYNC= 'before_check_ddl_blocked SIGNAL con4_started
                  WAIT_FOR status_shown2';
@@ -581,7 +581,7 @@ t3
 con1: Dropping the database tables
 DROP TABLE bup_ddl_blocker.t1, bup_ddl_blocker.t3;
 con1: Restoring the database
-RESTORE FROM "bup_ddl_blocker.bak";
+RESTORE FROM "bup_ddl_blocker.bak" OVERWRITE;
 backup_id
 #
 con1: Showing columns that were backed up
@@ -634,13 +634,13 @@ con1: Activate synchronization points fo
 SET DEBUG_SYNC= 'before_block_ddl SIGNAL bup_blocked WAIT_FOR status_shown';
 SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_started WAIT_FOR status_shown2';
 con1: Restoring database -- will block with lock
-RESTORE FROM "bup_ddl_blocker_orig.bak";
+RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE;
 con6: Wait for con1 to reach its synchronization point.
 SET DEBUG_SYNC= 'now WAIT_FOR bup_blocked';
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "RESTORE FROM%";
 state	info
-debug sync point: before_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak"
+debug sync point: before_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "OPTIMIZE TABLE bup_ddl_blocker.t1%";
 state	info
@@ -654,7 +654,7 @@ SET DEBUG_SYNC= 'now SIGNAL status_shown
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "RESTORE FROM%";
 state	info
-debug sync point: after_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak"
+debug sync point: after_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE
 con4: Activate synchronization point for DDL.
 SET DEBUG_SYNC= 'before_check_ddl_blocked SIGNAL con4_started
                  WAIT_FOR status_shown2';
@@ -806,7 +806,7 @@ con1: Dropping the database tables
 DROP DATABASE bup_ddl_blocker_1;
 DROP DATABASE bup_ddl_blocker_3;
 con1: Restoring the database
-RESTORE FROM "bup_ddl_blocker.bak";
+RESTORE FROM "bup_ddl_blocker.bak" OVERWRITE;
 backup_id
 #
 con1: Showing databases that were backed up
@@ -862,13 +862,13 @@ con1: Activate synchronization points fo
 SET DEBUG_SYNC= 'before_block_ddl SIGNAL bup_blocked WAIT_FOR status_shown';
 SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_started WAIT_FOR status_shown2';
 con1: Restoring database -- will block with lock
-RESTORE FROM "bup_ddl_blocker_orig.bak";
+RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE;
 con6: Wait for con1 to reach its synchronization point.
 SET DEBUG_SYNC= 'now WAIT_FOR bup_blocked';
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "RESTORE FROM%";
 state	info
-debug sync point: before_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak"
+debug sync point: before_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "CREATE DATABASE bup_ddl_blocker_1%";
 state	info
@@ -882,7 +882,7 @@ SET DEBUG_SYNC= 'now SIGNAL status_shown
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "RESTORE FROM%";
 state	info
-debug sync point: after_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak"
+debug sync point: after_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE
 con4: Activate synchronization point for DDL.
 SET DEBUG_SYNC= 'before_check_ddl_blocked SIGNAL con4_started
                  WAIT_FOR status_shown2';
@@ -1040,7 +1040,7 @@ con1: Dropping the database tables
 DROP DATABASE bup_ddl_blocker_2;
 DROP DATABASE bup_ddl_blocker_4;
 con1: Restoring the database
-RESTORE FROM "bup_ddl_blocker.bak";
+RESTORE FROM "bup_ddl_blocker.bak" OVERWRITE;
 backup_id
 #
 con1: Showing databases that were backed up
@@ -1112,13 +1112,13 @@ con1: Activate synchronization points fo
 SET DEBUG_SYNC= 'before_block_ddl SIGNAL bup_blocked WAIT_FOR status_shown';
 SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_started WAIT_FOR status_shown2';
 con1: Restoring database -- will block with lock
-RESTORE FROM "bup_ddl_blocker_orig.bak";
+RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE;
 con6: Wait for con1 to reach its synchronization point.
 SET DEBUG_SYNC= 'now WAIT_FOR bup_blocked';
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "RESTORE FROM%";
 state	info
-debug sync point: before_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak"
+debug sync point: before_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "ALTER DATABASE bup_ddl_blocker_2%";
 state	info
@@ -1132,7 +1132,7 @@ SET DEBUG_SYNC= 'now SIGNAL status_shown
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "RESTORE FROM%";
 state	info
-debug sync point: after_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak"
+debug sync point: after_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE
 con4: Activate synchronization point for DDL.
 SET DEBUG_SYNC= 'before_check_ddl_blocked SIGNAL con4_started
                  WAIT_FOR status_shown2';
@@ -1335,7 +1335,7 @@ DROP DATABASE bup_ddl_blocker_2;
 DROP DATABASE bup_ddl_blocker_3;
 DROP DATABASE bup_ddl_blocker_4;
 con1: Restoring the database
-RESTORE FROM "bup_ddl_blocker.bak";
+RESTORE FROM "bup_ddl_blocker.bak" OVERWRITE;
 backup_id
 #
 con1: Showing databases that were backed up
@@ -1428,13 +1428,13 @@ con1: Activate synchronization points fo
 SET DEBUG_SYNC= 'before_block_ddl SIGNAL bup_blocked WAIT_FOR status_shown';
 SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_started WAIT_FOR status_shown2';
 con1: Restoring database -- will block with lock
-RESTORE FROM "bup_ddl_blocker_orig.bak";
+RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE;
 con6: Wait for con1 to reach its synchronization point.
 SET DEBUG_SYNC= 'now WAIT_FOR bup_blocked';
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "RESTORE FROM%";
 state	info
-debug sync point: before_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak"
+debug sync point: before_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "CREATE INDEX 1t1col_b%";
 state	info
@@ -1448,7 +1448,7 @@ SET DEBUG_SYNC= 'now SIGNAL status_shown
 SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
 WHERE info LIKE "RESTORE FROM%";
 state	info
-debug sync point: after_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak"
+debug sync point: after_block_ddl	RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE
 con4: Activate synchronization point for DDL.
 SET DEBUG_SYNC= 'before_check_ddl_blocked SIGNAL con4_started
                  WAIT_FOR status_shown2';

=== modified file 'mysql-test/suite/backup/r/backup_errors.result'
--- a/mysql-test/suite/backup/r/backup_errors.result	2008-11-19 16:32:01 +0000
+++ b/mysql-test/suite/backup/r/backup_errors.result	2008-12-04 23:14:30 +0000
@@ -20,6 +20,8 @@ BACKUP DATABASE foo TO 'test.bak';
 ERROR 42000: Unknown database 'foo'
 BACKUP DATABASE test,foo,bdb,bar TO 'test.bak';
 ERROR 42000: Unknown database 'foo,bar'
+BACKUP DATABASE foo,test,bar,foo TO 'test.bak';
+ERROR 42000: Not unique database: 'foo'
 use adb;
 create table t1 (a int);
 create procedure p1() backup database test to 'test.bak';
@@ -133,3 +135,50 @@ SET DEBUG_SYNC= 'reset';
 DROP DATABASE db1;
 
 Done testing for Bug#38624
+
+Testing RESTORE ... OVERWRITE functionality
+See bug#34579
+
+Initialize
+CREATE DATABASE db1;
+USE db1;
+CREATE TABLE table1 (text VARCHAR(20));
+INSERT INTO table1 VALUES ('Inserted before');
+
+Backup database
+BACKUP DATABASE db1 TO 'overwrite.bak';
+backup_id
+#
+
+Insert more data and display
+INSERT INTO table1 VALUES ('Inserted after');
+SELECT * FROM table1;
+text
+Inserted before
+Inserted after
+
+Restore without OVERWRITE flag; will fail
+RESTORE FROM 'overwrite.bak';
+ERROR HY000: Database 'db1' already exists. Use OVERWRITE flag to overwrite.
+
+Restore with OVERWRITE flag; will succeed
+RESTORE FROM 'overwrite.bak' OVERWRITE;
+backup_id
+#
+
+Show that inserted value 2 is not there
+SELECT * FROM table1;
+text
+Inserted before
+DROP DATABASE db1;
+
+Restore after deleting db; will succeed
+RESTORE FROM 'overwrite.bak';
+backup_id
+#
+
+Show that inserted value 2 is not there
+SELECT * FROM table1;
+text
+Inserted before
+DROP DATABASE db1;

=== modified file 'mysql-test/suite/backup/r/backup_fkey.result'
--- a/mysql-test/suite/backup/r/backup_fkey.result	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_fkey.result	2008-11-17 09:57:51 +0000
@@ -43,10 +43,10 @@ SHOW VARIABLES LIKE 'foreign_key_checks%
 Variable_name	Value
 foreign_key_checks	ON
 Now restore the database.
-RESTORE FROM 'backup_fkey.bak';
+RESTORE FROM 'backup_fkey.bak' OVERWRITE;
 backup_id
 #
-RESTORE FROM 'backup_fkey_orig.bak';
+RESTORE FROM 'backup_fkey_orig.bak' OVERWRITE;
 backup_id
 #
 Show data
@@ -84,7 +84,7 @@ SHOW VARIABLES LIKE 'foreign_key_checks%
 Variable_name	Value
 foreign_key_checks	ON
 Restoring data
-RESTORE FROM 'backup_fkey.bak';
+RESTORE FROM 'backup_fkey.bak' OVERWRITE;
 backup_id
 #
 Verify foreign_key_checks = ON
@@ -97,7 +97,7 @@ SHOW VARIABLES LIKE 'foreign_key_checks%
 Variable_name	Value
 foreign_key_checks	OFF
 Restoring data
-RESTORE FROM 'backup_fkey.bak';
+RESTORE FROM 'backup_fkey.bak' OVERWRITE;
 backup_id
 #
 Verify foreign_key_checks = OFF

=== modified file 'mysql-test/suite/backup/r/backup_lock_myisam.result'
--- a/mysql-test/suite/backup/r/backup_lock_myisam.result	2008-11-28 21:35:11 +0000
+++ b/mysql-test/suite/backup/r/backup_lock_myisam.result	2008-12-04 23:14:30 +0000
@@ -54,7 +54,7 @@ DROP DATABASE db1;
 now start the restore and while the restore is running, fire the trigger
 activate synchronization points for restore.
 SET DEBUG_SYNC= 'restore_in_progress SIGNAL wait_for_restore WAIT_FOR finish';
-RESTORE FROM 'db1.bak';
+RESTORE FROM 'db1.bak' OVERWRITE;;
 From breakpoints:
 Wait for restore to reach its synchronization point.
 SET DEBUG_SYNC= 'now WAIT_FOR wait_for_restore';
@@ -64,7 +64,7 @@ WHERE info LIKE "RESTORE%";
 id	#
 command	Query
 state	debug sync point: restore_in_progress
-info	RESTORE FROM 'db1.bak'
+info	RESTORE FROM 'db1.bak' OVERWRITE
 From con2:
 Now do the insert while restore is running.
 INSERT INTO db2.t2 VALUES (0);
@@ -96,7 +96,7 @@ DELETE FROM db2.t2;
 now start the restore and while the restore is running, fire the trigger
 activate synchronization points for restore.
 SET DEBUG_SYNC= 'restore_in_progress SIGNAL wait_for_restore WAIT_FOR finish';
-RESTORE FROM 'db1.bak';
+RESTORE FROM 'db1.bak' OVERWRITE;;
 From breakpoints:
 Wait for restore to reach its synchronization point.
 SET DEBUG_SYNC= 'now WAIT_FOR wait_for_restore';
@@ -106,7 +106,7 @@ WHERE info LIKE "RESTORE%";
 id	#
 command	Query
 state	debug sync point: restore_in_progress
-info	RESTORE FROM 'db1.bak'
+info	RESTORE FROM 'db1.bak' OVERWRITE
 From con2:
 Now do the select while restore is running.
 SELECT * FROM db1.t1 limit 10;

=== modified file 'mysql-test/suite/backup/r/backup_logs.result'
--- a/mysql-test/suite/backup/r/backup_logs.result	2008-10-15 20:00:48 +0000
+++ b/mysql-test/suite/backup/r/backup_logs.result	2008-11-17 09:57:51 +0000
@@ -31,12 +31,12 @@ object	utf8
 Now starting real tests
 
 DROP DATABASE IF EXISTS backup_logs;
+PURGE BACKUP LOGS;
 CREATE DATABASE backup_logs;
 con1: Create table and new users.
 CREATE TABLE backup_logs.t1 (a char(30)) ENGINE=MYISAM;
 CREATE TABLE backup_logs.t2 (a char(30)) ENGINE=INNODB;
 CREATE TABLE backup_logs.t3 (a char(30)) ENGINE=MEMORY;
-CREATE TABLE backup_logs.t1_res (id BIGINT UNSIGNED NOT NULL) ENGINE=MEMORY;
 INSERT INTO backup_logs.t1 VALUES ("01 Test #1 - progress");
 INSERT INTO backup_logs.t1 VALUES ("02 Test #1 - progress");
 INSERT INTO backup_logs.t1 VALUES ("03 Test #1 - progress");
@@ -60,27 +60,28 @@ SET DEBUG_SYNC= 'after_backup_log_init  
 SET DEBUG_SYNC= 'after_backup_start_backup SIGNAL phase1    WAIT_FOR backup';
 SET DEBUG_SYNC= 'after_backup_validated    SIGNAL validated WAIT_FOR do_phase2';
 SET DEBUG_SYNC= 'after_backup_binlog       SIGNAL phase2    WAIT_FOR finish';
-con2: Send backup command.
+Start using a known backup id for a more definitive test.
+SET SESSION debug="+d,set_backup_id";
+con2: Send backup command. 
+con2: Backup id = 500.
 BACKUP DATABASE backup_logs to 'backup_logs_orig.bak';
 con1: Wait for the backup to be started.
 SET DEBUG_SYNC= 'now WAIT_FOR started';
 con1: Display progress
-SELECT MAX(backup_id) INTO @bup_id FROM mysql.backup_progress;
-INSERT INTO backup_logs.t1_res (id) VALUES (@bup_id);
-SELECT notes FROM mysql.backup_progress AS ob JOIN backup_logs.t1_res as t1 ON ob.backup_id = t1.id;
+SELECT notes FROM mysql.backup_progress WHERE backup_id = 500;
 notes
 starting
 con1: Let backup step to running state.
 SET DEBUG_SYNC= 'now SIGNAL do_run WAIT_FOR phase1';
 con1: Display progress
-SELECT notes FROM mysql.backup_progress AS ob JOIN backup_logs.t1_res as t1 ON ob.backup_id = t1.id;
+SELECT notes FROM mysql.backup_progress WHERE backup_id = 500;
 notes
 starting
 running
 con1: Let backup do the backup phase1.
 SET DEBUG_SYNC= 'now SIGNAL backup WAIT_FOR validated';
 con1: Display progress
-SELECT notes FROM mysql.backup_progress AS ob JOIN backup_logs.t1_res as t1 ON ob.backup_id = t1.id;
+SELECT notes FROM mysql.backup_progress WHERE backup_id = 500;
 notes
 starting
 running
@@ -88,7 +89,7 @@ validity point
 con1: Let backup do the backup phase2.
 SET DEBUG_SYNC= 'now SIGNAL do_phase2 WAIT_FOR phase2';
 con1: Display progress
-SELECT notes FROM mysql.backup_progress AS ob JOIN backup_logs.t1_res as t1 ON ob.backup_id = t1.id;
+SELECT notes FROM mysql.backup_progress WHERE backup_id = 500;
 notes
 starting
 running
@@ -99,8 +100,11 @@ con1: Let backup finish.
 SET DEBUG_SYNC= 'now SIGNAL finish';
 con2: Finish backup command
 backup_id
-#
-SELECT ob.* FROM mysql.backup_history AS ob JOIN backup_logs.t1_res AS t1 ON ob.backup_id = t1.id;;
+500
+FLUSH BACKUP LOGS;
+Turn off debugging session.
+SET SESSION debug="-d";
+SELECT * FROM mysql.backup_history WHERE backup_id = 500;;
 backup_id	#
 process_id	#
 binlog_pos	#
@@ -108,8 +112,8 @@ binlog_file	#
 backup_state	complete
 operation	backup
 error_num	0
-num_objects	4
-total_bytes	3981
+num_objects	3
+total_bytes	3971
 validity_point_time	#
 start_time	#
 stop_time	#
@@ -119,8 +123,8 @@ backup_file	#
 backup_file_path	#
 user_comment	
 command	BACKUP DATABASE backup_logs to 'backup_logs_orig.bak'
-drivers	MyISAM, Default, Snapshot
-SELECT obp.* FROM mysql.backup_progress AS obp JOIN backup_logs.t1_res AS t1 ON obp.backup_id = t1.id;
+drivers	MyISAM, Snapshot, Default
+SELECT * FROM mysql.backup_progress WHERE backup_id = 500;
 backup_id	object	start_time	stop_time	total_bytes	progress	error_num	notes
 #	backup kernel	#	#	0	0	0	starting
 #	backup kernel	#	#	0	0	0	running
@@ -128,26 +132,22 @@ backup_id	object	start_time	stop_time	to
 #	backup kernel	#	#	0	0	0	vp time
 #	backup kernel	#	#	0	0	0	running
 #	backup kernel	#	#	0	0	0	complete
-DELETE FROM backup_logs.t1_res;
 con2: Activate sync points for the backup statement.
 SET DEBUG_SYNC= 'after_backup_log_init      SIGNAL started WAIT_FOR do_run';
 SET DEBUG_SYNC= 'after_backup_start_restore SIGNAL running WAIT_FOR finish';
 con2: Send restore command.
-RESTORE FROM 'backup_logs_orig.bak';
+con2: Backup id = 501.
+RESTORE FROM 'backup_logs_orig.bak' OVERWRITE;
 con1: Wait for the restore to be started.
 SET DEBUG_SYNC= 'now WAIT_FOR started';
 con1: Display progress
-select * from backup_logs.t1_res;
-id
-SELECT MAX(backup_id) INTO @bup_id FROM mysql.backup_progress;
-INSERT INTO backup_logs.t1_res (id) VALUES (@bup_id);
-SELECT notes FROM mysql.backup_progress AS ob JOIN backup_logs.t1_res as t1 ON ob.backup_id = t1.id;
+SELECT notes FROM mysql.backup_progress WHERE backup_id = 501;
 notes
 starting
 con1: Let restore step to running state.
 SET DEBUG_SYNC= 'now SIGNAL do_run WAIT_FOR running';
 con1: Display progress
-SELECT notes FROM mysql.backup_progress AS ob JOIN backup_logs.t1_res as t1 ON ob.backup_id = t1.id;
+SELECT notes FROM mysql.backup_progress WHERE backup_id = 501;
 notes
 starting
 running
@@ -155,13 +155,11 @@ con1: Let restore do its job and finish.
 SET DEBUG_SYNC= 'now SIGNAL finish';
 con2: Finish restore command
 backup_id
-#
+501
+FLUSH BACKUP LOGS;
 SET DEBUG_SYNC= 'now SIGNAL complete';
 SET DEBUG_SYNC= 'now WAIT_FOR complete';
-DELETE FROM backup_logs.t1_res;
-SELECT MAX(backup_id) INTO @bup_id FROM mysql.backup_history WHERE command LIKE "RESTORE FROM%";
-INSERT INTO backup_logs.t1_res (id) VALUES (@bup_id);
-SELECT ob.* FROM mysql.backup_history AS ob JOIN backup_logs.t1_res AS t1 ON ob.backup_id = t1.id;;
+SELECT * FROM mysql.backup_history WHERE backup_id = 501;;
 backup_id	#
 process_id	#
 binlog_pos	#
@@ -169,8 +167,8 @@ binlog_file	#
 backup_state	complete
 operation	restore
 error_num	0
-num_objects	4
-total_bytes	1493
+num_objects	3
+total_bytes	1483
 validity_point_time	#
 start_time	#
 stop_time	#
@@ -179,23 +177,14 @@ username	root
 backup_file	#
 backup_file_path	#
 user_comment	
-command	RESTORE FROM 'backup_logs_orig.bak'
-drivers	MyISAM, Default, Snapshot
-SELECT obp.* FROM mysql.backup_progress AS obp JOIN backup_logs.t1_res AS t1 ON obp.backup_id = t1.id;
+command	RESTORE FROM 'backup_logs_orig.bak' OVERWRITE
+drivers	MyISAM, Snapshot, Default
+SELECT * FROM mysql.backup_progress WHERE backup_id = 501;
 backup_id	object	start_time	stop_time	total_bytes	progress	error_num	notes
 #	backup kernel	#	#	0	0	0	starting
 #	backup kernel	#	#	0	0	0	running
 #	backup kernel	#	#	0	0	0	complete
 SET DEBUG_SYNC= 'RESET';
-SET SESSION debug="d,set_backup_id";
-BACKUP DATABASE backup_logs to 'backup_logs_orig.bak';
-backup_id
-500
-SET SESSION debug="d";
-The backup id for this command should be 501.
-BACKUP DATABASE backup_logs to 'backup_logs_orig.bak';
-backup_id
-501
 The backup id for this command should be 502.
 BACKUP DATABASE backup_logs to 'backup_logs_orig.bak';
 backup_id
@@ -204,4 +193,12 @@ The backup id for this command should be
 BACKUP DATABASE backup_logs to 'backup_logs_orig.bak';
 backup_id
 503
+The backup id for this command should be 504.
+BACKUP DATABASE backup_logs to 'backup_logs_orig.bak';
+backup_id
+504
+The backup id for this command should be 505.
+BACKUP DATABASE backup_logs to 'backup_logs_orig.bak';
+backup_id
+505
 DROP DATABASE backup_logs;

=== modified file 'mysql-test/suite/backup/r/backup_logs_output.result'
--- a/mysql-test/suite/backup/r/backup_logs_output.result	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_logs_output.result	2008-11-17 11:17:59 +0000
@@ -1,5 +1,34 @@
 con1
-Display backup variables
+Clear the logs.
+SET @@global.backup_history_log = 'ON';
+SET @@global.backup_progress_log = 'ON';
+Display backup variable values from startup options file.
+SHOW VARIABLES LIKE 'backup_history%';
+Variable_name	Value
+backup_history_log	ON
+backup_history_log_file	MYSQLTEST_VARDIR/master-data/history.txt
+SHOW VARIABLES LIKE 'backup_progress%';
+Variable_name	Value
+backup_progress_log	ON
+backup_progress_log_file	MYSQLTEST_VARDIR/master-data/progress.txt
+SHOW VARIABLES LIKE 'log_backup_output';
+Variable_name	Value
+log_backup_output	TABLE
+Set the backup log file names to default values.
+SET @@global.backup_history_log_file = DEFAULT;
+SET @@global.backup_progress_log_file = DEFAULT;
+SET @@global.log_backup_output = 'TABLE';
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+See that the log names have been reset.
+SHOW VARIABLES LIKE 'backup_history%';
+Variable_name	Value
+backup_history_log	ON
+backup_history_log_file	MYSQLTEST_VARDIR/master-data/backup_history.log
+SHOW VARIABLES LIKE 'backup_progress%';
+Variable_name	Value
+backup_progress_log	ON
+backup_progress_log_file	MYSQLTEST_VARDIR/master-data/backup_progress.log
 SHOW VARIABLES LIKE 'backup_history_log';
 Variable_name	Value
 backup_history_log	ON
@@ -24,8 +53,6 @@ backup_progress_log	OFF
 SHOW VARIABLES LIKE 'log_backup_output';
 Variable_name	Value
 log_backup_output	NONE
-TRUNCATE TABLE mysql.backup_history;
-TRUNCATE TABLE mysql.backup_progress;
 Show the size of the logs
 SELECT count(*) FROM mysql.backup_history;
 count(*)
@@ -64,8 +91,8 @@ backup_progress_log	ON
 SHOW VARIABLES LIKE 'log_backup_output';
 Variable_name	Value
 log_backup_output	TABLE
-TRUNCATE TABLE mysql.backup_history;
-TRUNCATE TABLE mysql.backup_progress;
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
 BACKUP DATABASE bup_log TO 'bup_log.bak';
 backup_id
 #
@@ -79,6 +106,11 @@ count(*)
 FLUSH BACKUP LOGS;
 '---Checking backup logs when log_backup_output is TABLE---'
 '---and the progress log is turned off                   ---'
+Clear the logs.
+SET @@global.backup_history_log = 'ON';
+SET @@global.backup_progress_log = 'ON';
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
 SET @@global.backup_history_log = 'ON';
 SET @@global.backup_progress_log = 'OFF';
 Display backup variables
@@ -91,8 +123,6 @@ backup_progress_log	OFF
 SHOW VARIABLES LIKE 'log_backup_output';
 Variable_name	Value
 log_backup_output	TABLE
-TRUNCATE TABLE mysql.backup_history;
-TRUNCATE TABLE mysql.backup_progress;
 Show the size of the logs
 SELECT count(*) FROM mysql.backup_history;
 count(*)
@@ -113,6 +143,11 @@ count(*)
 FLUSH BACKUP LOGS;
 '---Checking backup logs when log_backup_output is TABLE---'
 '---and the history log is turned off                 ---'
+Clear the logs.
+SET @@global.backup_history_log = 'ON';
+SET @@global.backup_progress_log = 'ON';
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
 SET @@global.backup_history_log = 'OFF';
 SET @@global.backup_progress_log = 'ON';
 Display backup variables
@@ -125,8 +160,6 @@ backup_progress_log	ON
 SHOW VARIABLES LIKE 'log_backup_output';
 Variable_name	Value
 log_backup_output	TABLE
-TRUNCATE TABLE mysql.backup_history;
-TRUNCATE TABLE mysql.backup_progress;
 Show the size of the logs
 SELECT count(*) FROM mysql.backup_history;
 count(*)
@@ -145,6 +178,14 @@ SELECT count(*) FROM mysql.backup_progre
 count(*)
 6
 FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+Show the size of the logs
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+0
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+0
 '---Checking backup logs when log_backup_output is FILE---'
 SET @@global.log_backup_output = 'FILE';
 turning backup logs back on
@@ -160,8 +201,6 @@ backup_progress_log	ON
 SHOW VARIABLES LIKE 'log_backup_output';
 Variable_name	Value
 log_backup_output	FILE
-TRUNCATE TABLE mysql.backup_history;
-TRUNCATE TABLE mysql.backup_progress;
 BACKUP DATABASE bup_log TO 'bup_log.bak';
 backup_id
 #
@@ -173,6 +212,7 @@ SELECT count(*) FROM mysql.backup_progre
 count(*)
 0
 FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
 '---Checking backup logs when log_backup_output is TABLE, FILE---'
 SET @@global.log_backup_output = 'TABLE,FILE';
 Display backup variables
@@ -185,8 +225,6 @@ backup_progress_log	ON
 SHOW VARIABLES LIKE 'log_backup_output';
 Variable_name	Value
 log_backup_output	FILE,TABLE
-TRUNCATE TABLE mysql.backup_history;
-TRUNCATE TABLE mysql.backup_progress;
 BACKUP DATABASE bup_log TO 'bup_log.bak';
 backup_id
 #
@@ -198,6 +236,34 @@ SELECT count(*) FROM mysql.backup_progre
 count(*)
 6
 FLUSH BACKUP LOGS;
+SET GLOBAL backup_history_log=0;
+SET GLOBAL backup_progress_log=0;
+Should show 'OFF'
+SHOW VARIABLES LIKE 'backup%log';
+Variable_name	Value
+backup_history_log	OFF
+backup_progress_log	OFF
+SET GLOBAL backup_history_log=1;
+SET GLOBAL backup_progress_log=1;
+Should show 'ON'
+SHOW VARIABLES LIKE 'backup%log';
+Variable_name	Value
+backup_history_log	ON
+backup_progress_log	ON
+SET GLOBAL backup_history_log=OFF;
+SET GLOBAL backup_progress_log=OFF;
+Should show 'OFF'
+SHOW VARIABLES LIKE 'backup%log';
+Variable_name	Value
+backup_history_log	OFF
+backup_progress_log	OFF
+SET GLOBAL backup_history_log=DEFAULT;
+SET GLOBAL backup_progress_log=DEFAULT;
+After set default still should show 'ON'
+SHOW VARIABLES LIKE 'backup%log';
+Variable_name	Value
+backup_history_log	ON
+backup_progress_log	ON
 Cleanup
 DROP DATABASE bup_log;
 SET @@global.log_backup_output = 'TABLE';

=== added file 'mysql-test/suite/backup/r/backup_logs_purge.result'
--- a/mysql-test/suite/backup/r/backup_logs_purge.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/r/backup_logs_purge.result	2008-11-17 09:57:51 +0000
@@ -0,0 +1,425 @@
+SET @@global.log_backup_output = 'FILE,TABLE';
+PURGE BACKUP LOGS;
+
+Now starting real tests
+
+DROP DATABASE IF EXISTS backup_logs;
+CREATE DATABASE backup_logs;
+Create table and populate with data.
+CREATE TABLE backup_logs.t1 (a char(30)) ENGINE=MYISAM;
+CREATE TABLE backup_logs.t2 (a char(30)) ENGINE=INNODB;
+CREATE TABLE backup_logs.t3 (a char(30)) ENGINE=MEMORY;
+INSERT INTO backup_logs.t1 VALUES ("01 Test #1 - progress");
+INSERT INTO backup_logs.t1 VALUES ("02 Test #1 - progress");
+INSERT INTO backup_logs.t1 VALUES ("03 Test #1 - progress");
+INSERT INTO backup_logs.t1 VALUES ("04 Test #1 - progress");
+INSERT INTO backup_logs.t1 VALUES ("05 Test #1 - progress");
+INSERT INTO backup_logs.t1 VALUES ("06 Test #1 - progress");
+INSERT INTO backup_logs.t1 VALUES ("07 Test #1 - progress");
+INSERT INTO backup_logs.t2 VALUES ("01 Test #1 - progress");
+INSERT INTO backup_logs.t2 VALUES ("02 Test #1 - progress");
+INSERT INTO backup_logs.t2 VALUES ("03 Test #1 - progress");
+INSERT INTO backup_logs.t2 VALUES ("04 Test #1 - progress");
+INSERT INTO backup_logs.t2 VALUES ("05 Test #1 - progress");
+INSERT INTO backup_logs.t2 VALUES ("06 Test #1 - progress");
+INSERT INTO backup_logs.t3 VALUES ("01 Test #1 - progress");
+INSERT INTO backup_logs.t3 VALUES ("02 Test #1 - progress");
+INSERT INTO backup_logs.t3 VALUES ("03 Test #1 - progress");
+INSERT INTO backup_logs.t3 VALUES ("04 Test #1 - progress");
+SET SESSION debug="+d,set_backup_id";
+Do backup of database
+BACKUP DATABASE backup_logs to 'backup1.bak';
+backup_id
+500
+SET SESSION debug="-d";
+Do backup of database
+BACKUP DATABASE backup_logs to 'backup2.bak';
+backup_id
+501
+Do backup of database
+BACKUP DATABASE backup_logs to 'backup3.bak';
+backup_id
+502
+Do backup of database
+BACKUP DATABASE backup_logs to 'backup4.bak';
+backup_id
+503
+Do restore of database
+RESTORE from 'backup1.bak' OVERWRITE;
+backup_id
+504
+Do restore of database
+RESTORE from 'backup2.bak' OVERWRITE;
+backup_id
+505
+Do restore of database
+RESTORE from 'backup3.bak' OVERWRITE;
+backup_id
+506
+Do restore of database
+RESTORE from 'backup4.bak' OVERWRITE;
+backup_id
+507
+Display results from backup logs
+SELECT backup_id FROM mysql.backup_history;
+backup_id
+500
+501
+502
+503
+504
+505
+506
+507
+SELECT DISTINCT backup_id FROM mysql.backup_progress;
+backup_id
+500
+501
+502
+503
+504
+505
+506
+507
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+8
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+36
+Purge all backup log data prior to id = 502.
+PURGE BACKUP LOGS TO 502;
+Display results from backup logs
+SELECT backup_id FROM mysql.backup_history;
+backup_id
+502
+503
+504
+505
+506
+507
+SELECT DISTINCT backup_id FROM mysql.backup_progress;
+backup_id
+502
+503
+504
+505
+506
+507
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+6
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+24
+Purge all backup log data.
+PURGE BACKUP LOGS;
+Display results from backup logs
+SELECT backup_id FROM mysql.backup_history;
+backup_id
+SELECT DISTINCT backup_id FROM mysql.backup_progress;
+backup_id
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+0
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+0
+Cleanup the logs and images for later testing.
+PURGE BACKUP LOGS;
+SET @@time_zone = '+00:00';
+SET SESSION debug="+d,set_backup_id";
+Do backup of database
+BACKUP DATABASE backup_logs to 'backup1.bak';
+backup_id
+500
+SET SESSION debug="-d";
+Do backup of database
+BACKUP DATABASE backup_logs to 'backup2.bak';
+backup_id
+501
+Do backup of database
+BACKUP DATABASE backup_logs to 'backup3.bak';
+backup_id
+502
+SET SESSION debug="+d,set_log_time";
+Do backup of database
+BACKUP DATABASE backup_logs to 'backup4.bak';
+backup_id
+503
+SET SESSION debug="-d";
+Do restore of database
+RESTORE from 'backup1.bak' OVERWRITE;
+backup_id
+504
+Do restore of database
+RESTORE from 'backup2.bak' OVERWRITE;
+backup_id
+505
+Do restore of database
+RESTORE from 'backup3.bak' OVERWRITE;
+backup_id
+506
+SET SESSION debug="+d,set_log_time";
+Do restore of database
+RESTORE from 'backup4.bak' OVERWRITE;
+backup_id
+507
+SET SESSION debug="-d";
+Display the results.
+SELECT backup_id FROM mysql.backup_history;
+backup_id
+500
+501
+502
+503
+504
+505
+506
+507
+SELECT DISTINCT backup_id FROM mysql.backup_progress;
+backup_id
+500
+501
+502
+503
+504
+505
+506
+507
+SET @now_time= now();
+PURGE BACKUP LOGS BEFORE @now_time;
+SELECT backup_id FROM mysql.backup_history;
+backup_id
+503
+507
+SELECT DISTINCT backup_id FROM mysql.backup_progress;
+backup_id
+503
+507
+SET @@time_zone = @@global.time_zone;
+PURGE BACKUP LOGS;
+Perform backup
+SET SESSION debug="+d,set_backup_id";
+BACKUP DATABASE backup_logs TO '../bup_logs_dir.bak';
+backup_id
+500
+SET SESSION debug="-d";
+Ensure backup image file went to the correct location
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+1
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+6
+PURGE BACKUP LOGS TO 501;
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+0
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+0
+PURGE BACKUP LOGS BEFORE 123123;
+ERROR HY000: The datetime specified is invalid for the 'PURGE BACKUP LOGS BEFORE' command.
+SET @@global.log_backup_output = 'FILE';
+PURGE BACKUP LOGS TO 99999999;
+ERROR HY000: Removing backup log entries by date or backup_id requires logging to tables.
+PURGE BACKUP LOGS BEFORE @now_time;
+ERROR HY000: Removing backup log entries by date or backup_id requires logging to tables.
+SET @@global.log_backup_output = 'TABLE';
+Test backup and purge concurrent execution.
+PURGE BACKUP LOGS;
+Get rid of any lingering image files.
+SET DEBUG_SYNC= 'RESET';
+con2: Do some backups to add entries in logs.
+BACKUP DATABASE backup_logs to 'backup1.bak';
+backup_id
+#
+BACKUP DATABASE backup_logs to 'backup2.bak';
+backup_id
+#
+BACKUP DATABASE backup_logs to 'backup3.bak';
+backup_id
+#
+BACKUP DATABASE backup_logs to 'backup4.bak';
+backup_id
+#
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+4
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+24
+SET SESSION debug="+d,set_backup_id";
+con2: Activate sync points for the backup statement.
+SET DEBUG_SYNC= 'before_backup_done SIGNAL ready WAIT_FOR proceed';
+BACKUP DATABASE backup_logs to 'backup5.bak';
+con1: Wait for the backup to be ready.
+SET DEBUG_SYNC= 'now WAIT_FOR ready';
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC= 'now SIGNAL proceed';
+backup_id
+#
+SET SESSION debug="-d";
+There should be one row in this table: the backup id from last
+backup (500).
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+1
+SELECT backup_id, command FROM mysql.backup_history;
+backup_id	command
+500	BACKUP DATABASE backup_logs to 'backup5.bak'
+There should be one row in this table: the backup id from last
+backup (500). We should only see the complete progress 
+statement because all others were deleted while backup was
+in progress.
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+1
+SELECT * FROM mysql.backup_progress;
+backup_id	500
+object	backup kernel
+start_time	#
+stop_time	#
+total_bytes	0
+progress	0
+error_num	0
+notes	complete
+Now do the same test for restore.
+RESTORE FROM 'backup1.bak' OVERWRITE;
+backup_id
+#
+RESTORE FROM 'backup2.bak' OVERWRITE;
+backup_id
+#
+RESTORE FROM 'backup3.bak' OVERWRITE;
+backup_id
+#
+RESTORE FROM 'backup4.bak' OVERWRITE;
+backup_id
+#
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+5
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+13
+con2: Activate sync points for the backup statement.
+SET DEBUG_SYNC= 'before_restore_done SIGNAL ready WAIT_FOR proceed';
+RESTORE FROM 'backup5.bak' OVERWRITE;
+con1: Wait for the backup to be ready.
+SET DEBUG_SYNC= 'now WAIT_FOR ready';
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC= 'now SIGNAL proceed';
+backup_id
+#
+There should be one row in this table: the backup id from last
+restore (505).
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+1
+SELECT backup_id, command FROM mysql.backup_history;
+backup_id	command
+505	RESTORE FROM 'backup5.bak' OVERWRITE
+There should be one row in this table: the backup id from last
+restore (505). We should only see the complete progress 
+statement because all others were deleted while restore was
+in progress.
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+1
+SELECT * FROM mysql.backup_progress;
+backup_id	505
+object	backup kernel
+start_time	#
+stop_time	#
+total_bytes	0
+progress	0
+error_num	0
+notes	complete
+First, run some backups.
+BACKUP DATABASE backup_logs TO 'backup1.bak';
+backup_id
+#
+BACKUP DATABASE backup_logs TO 'backup2.bak';
+backup_id
+#
+BACKUP DATABASE backup_logs TO 'backup3.bak';
+backup_id
+#
+BACKUP DATABASE backup_logs TO 'backup4.bak';
+backup_id
+#
+BACKUP DATABASE backup_logs TO 'backup5.bak';
+backup_id
+#
+Test purges that do not meet criteria.
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+6
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+31
+PURGE BACKUP LOGS BEFORE '1988-10-12 12:00:00';
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+6
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+31
+PURGE BACKUP LOGS TO 0;
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+6
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+31
+Test empty logs (delete all entries).
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+6
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+31
+PURGE BACKUP LOGS TO 999999999;
+Check to be sure backup logs are empty (count(*) = 0).
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+0
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+0
+Run some more backups to generate more rows.
+BACKUP DATABASE backup_logs TO 'backup1.bak';
+backup_id
+#
+BACKUP DATABASE backup_logs TO 'backup2.bak';
+backup_id
+#
+BACKUP DATABASE backup_logs TO 'backup3.bak';
+backup_id
+#
+BACKUP DATABASE backup_logs TO 'backup4.bak';
+backup_id
+#
+BACKUP DATABASE backup_logs TO 'backup5.bak';
+backup_id
+#
+Test purges that do not meet criteria.
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+5
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+30
+PURGE BACKUP LOGS BEFORE '2024-10-12 12:00:00';
+Test empty logs (delete all entries).
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+0
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+0
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE backup_logs;
+PURGE BACKUP LOGS;

=== modified file 'mysql-test/suite/backup/r/backup_no_be.result'
--- a/mysql-test/suite/backup/r/backup_no_be.result	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_no_be.result	2008-11-17 09:57:51 +0000
@@ -3,10 +3,10 @@ CREATE DATABASE db1;
 USE db1;
 CREATE TABLE t1 (a int) ENGINE=Myisam;
 INSERT INTO t1 VALUES (1),(2),(3);
-SET SESSION debug="d,";
+SET SESSION debug="-d,";
 SELECT @@debug;
 @@debug
-d
+
 BACKUP DATABASE db1 TO 'db1.bak';
 backup_id
 #
@@ -17,7 +17,7 @@ WHERE command LIKE 'BACKUP DATABASE db1 
 SELECT drivers FROM mysql.backup_history WHERE backup_id=@id;
 drivers
 MyISAM
-SET SESSION debug="d,backup_test_dummy_be_factory";
+SET SESSION debug="+d,backup_test_dummy_be_factory";
 SELECT @@debug;
 @@debug
 d,backup_test_dummy_be_factory
@@ -32,11 +32,11 @@ WHERE command LIKE 'BACKUP DATABASE db1 
 SELECT drivers FROM mysql.backup_history WHERE backup_id=@id;
 drivers
 Default
-RESTORE FROM 'db1.bak';
+RESTORE FROM 'db1.bak' OVERWRITE;
 backup_id
 #
 SHOW TABLES IN db1;
 Tables_in_db1
 t1
 DROP DATABASE db1;
-SET GLOBAL debug="d,";
+SET GLOBAL debug="-d,";

=== modified file 'mysql-test/suite/backup/r/backup_no_data.result'
--- a/mysql-test/suite/backup/r/backup_no_data.result	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_no_data.result	2008-11-20 14:07:23 +0000
@@ -15,7 +15,7 @@ Database
 information_schema
 mysql
 test
-RESTORE FROM 'all.bak';
+RESTORE FROM 'all.bak' OVERWRITE;
 backup_id
 #
 SHOW DATABASES;
@@ -38,7 +38,7 @@ mysql
 test
 SHOW TABLES IN empty_db;
 Tables_in_empty_db
-RESTORE FROM 'all.bak';
+RESTORE FROM 'all.bak' OVERWRITE;
 backup_id
 #
 SHOW DATABASES;
@@ -66,7 +66,7 @@ empty_db
 mysql
 other_db
 test
-RESTORE FROM 'empty_db.bak';
+RESTORE FROM 'empty_db.bak' OVERWRITE;
 backup_id
 #
 USE empty_db;

=== modified file 'mysql-test/suite/backup/r/backup_nodata_driver.result'
--- a/mysql-test/suite/backup/r/backup_nodata_driver.result	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_nodata_driver.result	2008-11-21 15:02:34 +0000
@@ -1,7 +1,10 @@
+INSTALL PLUGIN example SONAME 'ha_example.so';
 DROP DATABASE IF EXISTS bup_nodata;
 DROP DATABASE IF EXISTS bup_data;
-Creating tables
-CREATE DATABASE bup_nodata;
+#
+# Create a database with tables that can work as
+# base tables for MERGE and FEDERATED.
+#
 CREATE DATABASE bup_data;
 CREATE TABLE bup_data.myisam1 (a int, b char(30)) ENGINE=MYISAM;
 CREATE TABLE bup_data.myisam2 (a int, b char(30)) ENGINE=MYISAM;
@@ -14,6 +17,10 @@ CREATE TABLE bup_data.f1 (
 `name` varchar(32) NOT NULL default ''
     )
 DEFAULT CHARSET=latin1;
+#
+# Create a database with tables from no-data engines.
+#
+CREATE DATABASE bup_nodata;
 CREATE TABLE bup_nodata.merge1 (a int, b char(30))
 ENGINE=MERGE UNION=(bup_data.myisam1, bup_data.myisam2, bup_data.myisam3);
 CREATE TABLE bup_nodata.f1 (
@@ -30,7 +37,9 @@ CREATE TABLE bup_nodata.e1 (
 Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
 Vapor_period smallint(4) unsigned DEFAULT '0' NOT NULL
 ) ENGINE=example;
-Inserting data
+#
+# Insert some data.
+#
 INSERT INTO bup_data.myisam1 VALUES (11, 'table 1');
 INSERT INTO bup_data.myisam1 VALUES (12, 'table 1');
 INSERT INTO bup_data.myisam1 VALUES (13, 'table 1');
@@ -45,7 +54,9 @@ INSERT INTO bup_data.f1 (id, name) VALUE
 INSERT INTO bup_data.f1 (id, `group`) VALUES (3, 42);
 INSERT INTO bup_data.f1 (id, `batch`) VALUES (4, 23);
 INSERT INTO bup_data.f1 (id, `qty`) VALUES (5, 1);
-show data
+#
+# Show the data.
+#
 SHOW FULL TABLES FROM bup_data;
 Tables_in_bup_data	Table_type
 f1	BASE TABLE
@@ -80,13 +91,21 @@ SELECT * FROM bup_nodata.b1;
 a	b	c
 SELECT * FROM bup_nodata.e1;
 Period	Vapor_period
+#
+# Backup the bup_data DB, which tables contain data.
+#
 BACKUP DATABASE bup_data TO 'bup_data.bak';
 backup_id
 #
+#
+# Backup the bup_nodata DB, which tables do not contain data.
+#
 BACKUP DATABASE bup_nodata TO 'bup_nodata.bak';
 backup_id
 #
-show data
+#
+# Show the data again. Backup did not modify them.
+#
 SHOW FULL TABLES FROM bup_data;
 Tables_in_bup_data	Table_type
 f1	BASE TABLE
@@ -121,8 +140,15 @@ SELECT * FROM bup_nodata.b1;
 a	b	c
 SELECT * FROM bup_nodata.e1;
 Period	Vapor_period
+#
+# Now drop the bup_data database.
+#
 DROP DATABASE bup_data;
-show data
+#
+# Show that the data have gone.
+# The MERGE and FEDERATED tables have errors since
+# their base tables have been dropped with bup_data.
+#
 SHOW FULL TABLES FROM bup_nodata;
 Tables_in_bup_nodata	Table_type
 b1	BASE TABLE
@@ -130,19 +156,34 @@ e1	BASE TABLE
 f1	BASE TABLE
 merge1	BASE TABLE
 SELECT * FROM bup_nodata.merge1;
-ERROR 42S02: Table 'bup_data.myisam1' doesn't exist
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
 SELECT * FROM bup_nodata.f1;
 Got one of the listed errors
 SELECT * FROM bup_nodata.b1;
 a	b	c
 SELECT * FROM bup_nodata.e1;
 Period	Vapor_period
+#
+# Now drop the bup_nodata database too.
+#
 DROP DATABASE bup_nodata;
-Restoring nodata database.
-RESTORE FROM 'bup_nodata.bak';
-backup_id
 #
-show data
+# Now try to restore the bup_nodata database. This fails because
+# restore opens the tables for filling them with data, even when
+# they were empty on backup. 'bup_nodata.bak' does not contain
+# the base tables for the MERGE and FEDERATED tables.
+# NOTE: Since restore fails after restoring the meta data,
+# after creating the tables that is, we have the same
+# situation as before. The tables exist, but the base
+# tables for MERGE and FEDERATED do not exist.
+#
+RESTORE FROM 'bup_nodata.bak' OVERWRITE;
+Got one of the listed errors
+#
+# Show what we have.
+# NOTE: If restore would work as all or nothing,
+# all of the SHOW and SELECT statements in this section would fail.
+#
 SHOW FULL TABLES FROM bup_nodata;
 Tables_in_bup_nodata	Table_type
 b1	BASE TABLE
@@ -150,18 +191,24 @@ e1	BASE TABLE
 f1	BASE TABLE
 merge1	BASE TABLE
 SELECT * FROM bup_nodata.merge1;
-ERROR 42S02: Table 'bup_data.myisam1' doesn't exist
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
 SELECT * FROM bup_nodata.f1;
 Got one of the listed errors
 SELECT * FROM bup_nodata.b1;
 a	b	c
 SELECT * FROM bup_nodata.e1;
 Period	Vapor_period
-Restoring data database.
+#
+# Now restore the bup_data database as well.
+#
 RESTORE FROM 'bup_data.bak';
 backup_id
 #
-show data
+#
+# Show that everything is well.
+# NOTE: If restore would work as all or nothing,
+# the bup_nodata tables would not exist here.
+#
 SHOW FULL TABLES FROM bup_data;
 Tables_in_bup_data	Table_type
 f1	BASE TABLE
@@ -196,5 +243,72 @@ SELECT * FROM bup_nodata.b1;
 a	b	c
 SELECT * FROM bup_nodata.e1;
 Period	Vapor_period
+#
+# Now restore the bup_nodata database and see if it is the same
+# as above. Note that this step would not be required here
+# because all bup_nodata tables have no data and were created
+# by the failed restore. Anyway, the correct approach is to do a
+# succeeding restore before assuming that everything exists again.
+#
+RESTORE FROM 'bup_nodata.bak' OVERWRITE;
+backup_id
+#
+#
+# Show that everything is well.
+#
+SHOW FULL TABLES FROM bup_nodata;
+Tables_in_bup_nodata	Table_type
+b1	BASE TABLE
+e1	BASE TABLE
+f1	BASE TABLE
+merge1	BASE TABLE
+SELECT * FROM bup_nodata.merge1;
+a	b
+11	table 1
+12	table 1
+13	table 1
+21	table 2
+22	table 2
+23	table 2
+31	table 3
+32	table 3
+33	table 3
+SELECT * FROM bup_nodata.f1;
+id	group	batch	qty	name
+1	0	0	0	foo
+2	0	0	0	fee
+3	42	0	0	
+4	0	23	0	
+5	0	0	1	
+SELECT * FROM bup_nodata.b1;
+a	b	c
+SELECT * FROM bup_nodata.e1;
+Period	Vapor_period
+#
+# Now drop the bup_data database with the base tables again.
+#
 DROP DATABASE bup_data;
+#
+# Show that the data have gone.
+# The MERGE and FEDERATED tables have errors since
+# their base tables have been dropped with bup_data.
+#
+SHOW FULL TABLES FROM bup_nodata;
+Tables_in_bup_nodata	Table_type
+b1	BASE TABLE
+e1	BASE TABLE
+f1	BASE TABLE
+merge1	BASE TABLE
+SELECT * FROM bup_nodata.merge1;
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+SELECT * FROM bup_nodata.f1;
+Got one of the listed errors
+SELECT * FROM bup_nodata.b1;
+a	b	c
+SELECT * FROM bup_nodata.e1;
+Period	Vapor_period
+#
+# Cleanup.
+#
 DROP DATABASE bup_nodata;
+UNINSTALL PLUGIN example;

=== modified file 'mysql-test/suite/backup/r/backup_security.result'
--- a/mysql-test/suite/backup/r/backup_security.result	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_security.result	2008-11-17 09:57:51 +0000
@@ -49,7 +49,7 @@ BACKUP DATABASE backup_test to 'bup_with
 backup_id
 #
 no_rights: Attempting restore. Should succeed
-RESTORE FROM 'bup_with_rights.bak';
+RESTORE FROM 'bup_with_rights.bak' OVERWRITE;
 backup_id
 #
 SELECT * FROM backup_test.t1;
@@ -62,7 +62,7 @@ a
 06 Test #1 - super privilege
 07 Test #1 - super privilege
 default: Do restore to ensure it still works with default test user.
-RESTORE FROM 'backup_test_orig.bak';
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
 backup_id
 #
 SELECT * FROM backup_test.t1;

=== modified file 'mysql-test/suite/backup/r/backup_snapshot.result'
--- a/mysql-test/suite/backup/r/backup_snapshot.result	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_snapshot.result	2008-11-17 09:57:51 +0000
@@ -60,7 +60,7 @@ backup_id
 con1: Dropping the database
 DROP TABLE bup_snapshot.t1;
 con1: Restoring the database
-RESTORE FROM "bup_snapshot.bak";
+RESTORE FROM "bup_snapshot.bak" OVERWRITE;
 backup_id
 #
 con1: Showing the data (no new data should be here).
@@ -106,7 +106,7 @@ backup_id
 con1: Dropping the database
 DROP TABLE bup_snapshot.t1;
 con1: Restoring the database
-RESTORE FROM "bup_snapshot.bak";
+RESTORE FROM "bup_snapshot.bak" OVERWRITE;
 backup_id
 #
 con1: Showing the data (no new data should be here).

=== modified file 'mysql-test/suite/backup/r/backup_timeout.result'
--- a/mysql-test/suite/backup/r/backup_timeout.result	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_timeout.result	2008-11-19 22:01:28 +0000
@@ -71,3 +71,4 @@ SHOW VARIABLES LIKE 'backup_wait%';
 Variable_name	Value
 backup_wait_timeout	50
 DROP DATABASE bup_ddl_blocker;
+SET DEBUG_SYNC= 'reset';

=== removed file 'mysql-test/suite/backup/r/backup_view_on_view.result'
--- a/mysql-test/suite/backup/r/backup_view_on_view.result	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_view_on_view.result	1970-01-01 00:00:00 +0000
@@ -1,38 +0,0 @@
-SET GLOBAL debug="d,backup:d,backup_data";
-DROP DATABASE IF EXISTS db1;
-CREATE DATABASE db1;
-CREATE TABLE db1.t1(a int) ENGINE=INNODB;
-CREATE VIEW db1.v1 AS SELECT * FROM db1.t1;
-CREATE VIEW db1.v2 AS SELECT * FROM db1.v1;
-INSERT INTO db1.t1 VALUES (1),(2),(3),(5),(7),(11);
-BACKUP DATABASE db1 TO 'test.bak';
-backup_id
-#
-RESTORE FROM 'test.bak';
-backup_id
-#
-SELECT * FROM db1.v2;
-a
-1
-2
-3
-5
-7
-11
-SELECT * FROM db1.v1;
-a
-1
-2
-3
-5
-7
-11
-SELECT * FROM db1.t1;
-a
-1
-2
-3
-5
-7
-11
-DROP DATABASE db1;

=== added file 'mysql-test/suite/backup/r/backup_vp_nontx.result'
--- a/mysql-test/suite/backup/r/backup_vp_nontx.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/r/backup_vp_nontx.result	2008-11-20 09:49:34 +0000
@@ -0,0 +1,115 @@
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE IF EXISTS bup_vp;
+CREATE DATABASE bup_vp;
+
+Starting Test
+
+con_bup: Creating tables
+CREATE TABLE bup_vp.t1 (col_a CHAR(40)) ENGINE=MEMORY;
+con_bup: Loading data
+con_bup: Scenario a) - commited before backup
+INSERT INTO bup_vp.t1 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("05 Some data to test");
+
+con_bup: Show the data before we start backup
+SELECT * FROM bup_vp.t1;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+
+Scenario (b): Insert in progress blocks CB and is included in backup
+con_ntx1: Start insert and stop it in the middle of processing
+con_ntx1: Make insert stop in the middle of execution
+SET DEBUG_SYNC= 'after_insert_locked_tables SIGNAL insert_started
+                   WAIT_FOR complete_insert';
+INSERT INTO bup_vp.t1 VALUES ("ntx1: 06 Some data to test");
+
+con_bup: Activate synchronization points for BACKUP.
+SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL sync_complete_insert';
+SET DEBUG_SYNC= 'before_backup_data_lock SIGNAL try_insert
+                 WAIT_FOR insert_blocked';
+SET DEBUG_SYNC= 'after_backup_binlog SIGNAL commit_unblocked
+                 WAIT_FOR finish_bup';
+con_bup: Backing up database -- will block with lock
+BACKUP DATABASE bup_vp TO "bup_vp.bak";
+
+SET DEBUG_SYNC= 'now WAIT_FOR sync_complete_insert';
+Backup has been blocked by ongoing insert
+SET DEBUG_SYNC= 'now SIGNAL complete_insert';
+
+con_ntx1: Reap insert
+Check that record has been inserted; Should be 1 record
+SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx1%';
+col_a
+ntx1: 06 Some data to test
+
+con_ntx2: Wait until backup has set CB, then try to insert
+SET DEBUG_SYNC= 'now WAIT_FOR try_insert';
+SET DEBUG_SYNC= 'wait_if_global_read_lock SIGNAL sync_insert_blocked';
+INSERT INTO bup_vp.t1 VALUES ("ntx2: Should NOT be in backup");
+
+SET DEBUG_SYNC= 'now WAIT_FOR sync_insert_blocked';
+Insert in ntx2 is blocked and should not be in t1; Should be 0 records
+SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx2%';
+col_a
+
+SET DEBUG_SYNC= 'now SIGNAL insert_blocked';
+
+con_ntx1: Backup has now released CB. Perform insert
+SET DEBUG_SYNC= 'now WAIT_FOR commit_unblocked';
+INSERT INTO bup_vp.t1 VALUES ("ntx1: Should NOT be in backup");
+SET DEBUG_SYNC= 'now SIGNAL finish_bup';
+
+con_ntx1: Reap backup
+backup_id
+#
+
+con_bup: Showing data after updates and backup
+SELECT * FROM bup_vp.t1;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+ntx1: 06 Some data to test
+ntx2: Should NOT be in backup
+ntx1: Should NOT be in backup
+con_bup: Dropping the database
+DROP TABLE bup_vp.t1;
+DROP DATABASE bup_vp;
+con_bup: Restoring the database
+RESTORE FROM "bup_vp.bak";
+backup_id
+#
+
+con_bup: Showing the data after restore
+SELECT * FROM bup_vp.t1;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+ntx1: 06 Some data to test
+
+Verifying results:
+
+T1 should have changes from con_ntx1; Should be 1 record
+SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx1%';
+col_a
+ntx1: 06 Some data to test
+
+T1 should not have the changes from con_ntx2; Should be 0 records
+SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx2%';
+col_a
+
+con_bup: Cleanup
+DROP DATABASE bup_vp;
+SET DEBUG_SYNC= 'RESET';

=== added file 'mysql-test/suite/backup/r/backup_vp_tx.result'
--- a/mysql-test/suite/backup/r/backup_vp_tx.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/r/backup_vp_tx.result	2008-11-20 09:49:34 +0000
@@ -0,0 +1,203 @@
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE IF EXISTS bup_vp;
+CREATE DATABASE bup_vp;
+
+Starting Test
+
+con_bup: Creating tables
+CREATE TABLE bup_vp.t1 (col_a CHAR(40)) ENGINE=INNODB;
+CREATE TABLE bup_vp.t2 (col_a CHAR(40)) ENGINE=INNODB;
+CREATE TABLE bup_vp.t3 (col_a CHAR(40)) ENGINE=INNODB;
+
+con_bup: Loading data
+con_bup: Scenario a) - commited before backup
+INSERT INTO bup_vp.t1 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("05 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("05 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("05 Some data to test");
+
+con_bup: Show the data before we start backup
+SELECT * FROM bup_vp.t1;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+SELECT * FROM bup_vp.t2;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+SELECT * FROM bup_vp.t3;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+
+Scenario d) - commit after VP; tx not included in backup
+con_tx3: Start transaction but do not commit
+BEGIN;
+INSERT INTO bup_vp.t3 VALUES ("tx3: 06 Should NOT be in backup");
+
+Scenario b) - Commit in progress blocks CB; tx is included in backup
+con_tx1: Get a transaction going and stop in the middle of commit
+BEGIN;
+INSERT INTO bup_vp.t1 VALUES ("tx1: 06 Some data to test");
+con_tx1: Make commit stop in the middle of execution
+SET DEBUG_SYNC= 'within_ha_commit_trans SIGNAL commit_started
+                       WAIT_FOR complete_commit';
+COMMIT;
+
+Scenario c) - commit blocked by CB; tx not included in backup
+con_tx2: Wait until tx1 has started
+SET DEBUG_SYNC= 'now WAIT_FOR commit_started';
+con_tx2: Start transaction but do not commit
+BEGIN;
+INSERT INTO bup_vp.t2 VALUES ("tx2: 06 Should NOT be in backup");
+
+con_bup: Activate synchronization points for BACKUP.
+SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL sync_complete_commit';
+SET DEBUG_SYNC= 'before_backup_data_lock SIGNAL try_commit 
+                 WAIT_FOR commit_blocked';
+SET DEBUG_SYNC= 'after_backup_binlog SIGNAL commit_unblocked
+                 WAIT_FOR finish_bup';
+con_bup: Backing up database -- will block with lock
+BACKUP DATABASE bup_vp TO "bup_vp.bak";
+
+SET DEBUG_SYNC= 'now WAIT_FOR sync_complete_commit';
+Backup has been blocked by ongoing commit
+Check that con_tx1 has not committed; Should be 0 records
+SELECT * FROM bup_vp.t1 WHERE col_a like 'tx1%';
+col_a
+
+SET DEBUG_SYNC= 'now SIGNAL complete_commit';
+
+con_tx1: Reap commit
+Check that con_tx1 has committed; Should be 1 record
+SELECT * FROM bup_vp.t1 WHERE col_a like 'tx1%';
+col_a
+tx1: 06 Some data to test
+
+
+con_tx2: Commit request will be blocked by CB
+SET DEBUG_SYNC= 'now WAIT_FOR try_commit';
+SET DEBUG_SYNC= 'wait_if_global_read_lock SIGNAL sync_commit_blocked';
+COMMIT;
+
+SET DEBUG_SYNC= 'now WAIT_FOR sync_commit_blocked';
+Check that con_tx2 has not committed; Should be 0 records
+SELECT * FROM bup_vp.t2 WHERE col_a like 'tx2%';
+col_a
+
+SET DEBUG_SYNC= 'now SIGNAL commit_blocked';
+
+con_bup: Reap commit
+con_tx2: Backup has now released CB.
+Check that con_tx2 has committed; Should be 1 record
+SELECT * FROM bup_vp.t2 WHERE col_a like 'tx2%';
+col_a
+tx2: 06 Should NOT be in backup
+
+
+con_tx3: Backup has now released CB. Commit transaction
+SET DEBUG_SYNC= 'now WAIT_FOR commit_unblocked';
+COMMIT;
+SET DEBUG_SYNC= 'now SIGNAL finish_bup';
+
+con_bup: Reap backup
+backup_id
+#
+
+con_bup: Showing data after updates and backup
+SELECT * FROM bup_vp.t1;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+tx1: 06 Some data to test
+SELECT * FROM bup_vp.t2;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+tx2: 06 Should NOT be in backup
+SELECT * FROM bup_vp.t3;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+tx3: 06 Should NOT be in backup
+con_bup: Dropping the database
+DROP TABLE bup_vp.t1;
+DROP TABLE bup_vp.t2;
+DROP TABLE bup_vp.t3;
+DROP DATABASE bup_vp;
+con_bup: Restoring the database
+RESTORE FROM "bup_vp.bak";
+backup_id
+#
+
+con_bup: Showing the data after restore (tx2 and tx3 should not be there)
+SELECT * FROM bup_vp.t1;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+tx1: 06 Some data to test
+SELECT * FROM bup_vp.t2;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+SELECT * FROM bup_vp.t3;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+
+Verifying results:
+
+T1 should have changes from con_tx1; Should be 1 record
+SELECT * FROM bup_vp.t1 WHERE col_a like 'tx1%';
+col_a
+tx1: 06 Some data to test
+
+T2 should not have the changes from con_tx2; Should be 0 records
+SELECT * FROM bup_vp.t2 WHERE col_a like 'tx2%';
+col_a
+
+T3 should not have the changes from con_tx3; Should be 0 records
+SELECT * FROM bup_vp.t3 WHERE col_a like 'tx3%';
+col_a
+
+con_bup: Cleanup
+DROP DATABASE bup_vp;
+SET DEBUG_SYNC= 'RESET';

=== modified file 'mysql-test/suite/backup/t/backup.test'
--- a/mysql-test/suite/backup/t/backup.test	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup.test	2008-11-17 09:57:51 +0000
@@ -434,7 +434,7 @@ SELECT * FROM bup_delete.me;
 
 --echo do restore
 --replace_column 1 #
-RESTORE FROM 'bup_delete.bak';
+RESTORE FROM 'bup_delete.bak' OVERWRITE;
 
 --echo show the data
 SELECT * FROM bup_delete.me;
@@ -472,7 +472,7 @@ BACKUP DATABASE bup_default TO 'bup_defa
 
 --echo Restore the database.
 --replace_column 1 #
-RESTORE FROM 'bup_default_timestamp.bak';
+RESTORE FROM 'bup_default_timestamp.bak' OVERWRITE;
 
 --echo Show data after restore (timestamp should be same as above).
 SELECT * FROM bup_default.time_t1;

=== modified file 'mysql-test/suite/backup/t/backup_backupdir.test'
--- a/mysql-test/suite/backup/t/backup_backupdir.test	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_backupdir.test	2008-11-17 09:57:51 +0000
@@ -41,7 +41,7 @@ BACKUP DATABASE bup_backupdir TO 'bup_ba
 
 --echo Perform restore
 --replace_column 1 #
-RESTORE FROM 'bup_backupdir1.bak';
+RESTORE FROM 'bup_backupdir1.bak' OVERWRITE;
 
 --echo Now do the backup and restore by specifying a path.
 
@@ -54,7 +54,7 @@ BACKUP DATABASE bup_backupdir TO '../bup
 
 --echo Perform restore
 --replace_column 1 #
-RESTORE FROM '../bup_backupdir2.bak';
+RESTORE FROM '../bup_backupdir2.bak' OVERWRITE;
 
 --echo Perform backup
 --replace_column 1 #

=== modified file 'mysql-test/suite/backup/t/backup_commit_backup.test'
--- a/mysql-test/suite/backup/t/backup_commit_backup.test	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_commit_backup.test	2008-11-17 09:57:51 +0000
@@ -216,7 +216,7 @@ SELECT release_lock("sync");
 echo Checking contents of the backup image;
 
 replace_column 1 #;
-RESTORE FROM 'db1.bak';
+RESTORE FROM 'db1.bak' OVERWRITE;
 
 SELECT * FROM db1.t1;
 SELECT * FROM db1.t2;

=== removed file 'mysql-test/suite/backup/t/backup_commit_blocker.test'
--- a/mysql-test/suite/backup/t/backup_commit_blocker.test	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_commit_blocker.test	1970-01-01 00:00:00 +0000
@@ -1,800 +0,0 @@
-#
-# This test is for the commit blocker
-# The goals of the test should be to ensure the following assumptions for
-# the behaviour of the commit blocker hold true.
-#
-# a) transactions in progress are not committed until after the backup
-# b) transactions that are committing are allowed to commit
-# c) transactions that have not started are allowed to start but do not commit
-# d) non-transaction statements in progress are allowed to finish
-# e) non-transaction statements that have not started are blocked
-#
-# The results of the backup should show (based on statements above):
-#
-# a) Test result for this assumption: Not included in backup
-# b) Test result for this assumption: Included in backup
-# c) Test result for this assumption: Not included in backup
-# d) Test result for this assumption: Included in backup
-# e) Test result for this assumption: Not included in backup
-#
-# Note: the statements above assume statements that change data.
-#
-# The test shall run three sets of data manipulation statements. 
-#
-# 1) transactional statments only
-# 2) non-transactional statements only
-# 3) mix of both transactional and non-transactional statements
-#
-# TODO : Add a native driver to the test when one becomes available
-#
-
---source include/have_innodb.inc
---source include/have_debug_sync.inc
---source include/not_embedded.inc
-
---disable_warnings
-SET DEBUG_SYNC= 'RESET';
-DROP DATABASE IF EXISTS bup_commit_blocker;
---error 0,1
---remove_file $MYSQLTEST_VARDIR/master-data/bup_commit_blocker.bak;
---enable_warnings
-
-CREATE DATABASE bup_commit_blocker;
-
-#
-# Connections used in this test
-#
-# con1 - used to create data, load data, and run the backup 
-# con2 - used for setting up transactions in progress
-# con3 - used for setting up transactions in commit
-# con4 - used for setting up transactions about to start
-# con5 - used to show status
-# con6 - used for setting up non-transactions in progress
-# con7 - used for setting up non-transactions about to start
-#
-
-connect (con1,localhost,root,,);
-connect (con2,localhost,root,,);
-connect (con3,localhost,root,,);
-connect (con4,localhost,root,,);
-connect (con5,localhost,root,,);
-connect (con6,localhost,root,,);
-connect (con7,localhost,root,,);
-
-#
-# Note: Originally we used SELECT ... FROM INFORMATION_SCHEMA.PROCESSLIST; to show status of 
-# the various connections participating in the test. But INFORMATION_SCHEMA.PROCESSLIST implementation
-# proved to be not relaiable. From time to time (nondeterminisrtically) test hanged on these SELECTs.
-# As showing the status is not essential for the test (we test correctness by checking the contents of
-# the created backup image), the selects are commented out now. They can be re-enabled when
-# I_S.PROCESSLIST is in a better shape.
-#
-
-connection con1;
-
-#
-# Test 1 - transactional statements only
-#
-
---echo 
---echo Starting Test 1
---echo 
-
-#
-# Test 1 sequence diagram (not UML)
-#
-#   con1     con2     con3     con4     con5
-#  (setup)    |        |        |        |
-#     |       |        |        |        |
-#     |     BEGIN      |        |        |
-#     |    UPDATE t1   |        |        |
-#     |       |      BEGIN      |        |
-#     |       |     INSERT t2   |        |
-#     |       |     INSERT t2   |        |
-#     |       |        |        |    show status
-#   BACKUP    |        |        |        |
-#     |       |      COMMIT     |        |
-#     |       |        |        |    show status
-#     |       |        |      BEGIN      |
-#     |       |        |        |    show status
-#     |    DELETE t1   |        |        |
-#     |     COMMIT     |        |        |
-#     |       |      <...>      |        |
-#     |       |        |     UPDATE t3   |
-#     |       |        |     COMMIT      |
-#   <...>     |        |        |        |
-# (results)   |        |        |        |
-#
-# Note: The resume of the commands is indicated with <...> and
-#       may occur in any order.
-#
-
-# Create transaction tables and load them with data.
---echo con1: Creating tables
-CREATE TABLE bup_commit_blocker.t1 (col_a CHAR(40)) ENGINE=INNODB;
-CREATE TABLE bup_commit_blocker.t2 (col_a CHAR(40)) ENGINE=INNODB;
-CREATE TABLE bup_commit_blocker.t3 (col_a CHAR(40)) ENGINE=INNODB;
-
---echo con1: Loading data
-INSERT INTO bup_commit_blocker.t1 VALUES ("01 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("02 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("03 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("04 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("05 Some data to test");
-
-INSERT INTO bup_commit_blocker.t2 VALUES ("01 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("02 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("03 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("04 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("05 Some data to test");
-
-INSERT INTO bup_commit_blocker.t3 VALUES ("01 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("02 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("03 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("04 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("05 Some data to test");
-
---echo con1: Show that the new data doesn't exist before backup.
-SELECT * FROM bup_commit_blocker.t1;
-SELECT * FROM bup_commit_blocker.t2;
-SELECT * FROM bup_commit_blocker.t3;
-
-connection con2;
-
---echo con2: Get a transaction going and stop in the middle
---echo Assumption (a): TRX in progress is not included in backup
-BEGIN;
-  UPDATE bup_commit_blocker.t1 SET col_a = "con2: CHANGED" WHERE col_a LIKE '01%';
-
-connection con3;
-
---echo con3: Start a transaction and send commit after lock is taken
---echo Assumption (b): TRX in commit is included in backup
-BEGIN;
-  INSERT INTO bup_commit_blocker.t2 VALUES ("con3: 04 Some data to test");
-  INSERT INTO bup_commit_blocker.t2 VALUES ("con3: 05 Some data to test");
-
-connection con1;
-
-#
-# We must start the backup and allow it to gather the metadata first.
-# We stop (with a sync point) the backup after the metadata but before
-# the commit blocker.
-#
---echo con1: Activate synchronization points for BACKUP.
-# Before blocking commits, pause to show processlist state.
-# Before going to wait for the protection against global read lock to
-# disappear, signal about the wait, so that another thread can continue.
-# When COMMIT finishes, it releases the protection against global read lock,
-# which would allow BACKUP to continue while COMMIT also continues and
-# signals "commit_done". It is important that BACKUP does not run in
-# parallel and send another signal without waiting for the commit_done
-# signal to be processed. So BACKUP itself has to wait for that signal
-# after awaking and taking the global read lock. Only then BACKUP
-# can proceed and send a signal telling that it took the global read
-# lock. Unfortunately DEBUG_SYNC does not allow a sync point to emit a
-# signal after a wait_for action. So we need to send the signal in a later
-# sync point. For this test it is not important where this signal is sent,
-# as long as it is sent while BACKUP holds the global read lock.
-# Here we do it "before_backup_unblock_commit", where we have to
-# synchronize anyway.
-SET DEBUG_SYNC= 'before_commit_block SIGNAL bup_commit_block
-                 WAIT_FOR bup_go_read_lock';
-SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL bup_read_lock';
-SET DEBUG_SYNC= 'before_backup_data_lock WAIT_FOR commit_done';
-SET DEBUG_SYNC= 'before_backup_unblock_commit SIGNAL bup_read_locked
-                 WAIT_FOR finish';
---echo con1: Backing up database -- will block with lock
-send BACKUP DATABASE bup_commit_blocker TO "bup_commit_blocker.bak";
-
-connection con5;
-
---echo con5: Wait for BACKUP to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR bup_commit_block';
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "BACKUP DATABASE%";
-
-connection con3;
-
---echo con3: Activate synchronization points for COMMIT.
-SET DEBUG_SYNC= 'within_ha_commit_trans SIGNAL commit_read_locked
-                 WAIT_FOR commit_go_done';
-SET DEBUG_SYNC= 'after_commit SIGNAL commit_done WAIT_FOR finish';
---echo con3: Starting commit -- will block on sync point
-send COMMIT;
-
-connection con5;
-
---echo con5: Wait for COMMIT to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR commit_read_locked';
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "COMMIT%";
-
---echo con5: Let BACKUP run until the next sync point.
-SET DEBUG_SYNC= 'now SIGNAL bup_go_read_lock WAIT_FOR bup_read_lock';
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "BACKUP DATABASE%";
-
---echo con5: Let COMMIT continue until end of statement.
---echo con5: The completed COMMIT implicitly wakes BACKUP.
---echo con5: So wait for BACKUP to reach the next synchronization point.
-SET DEBUG_SYNC= 'now SIGNAL commit_go_done WAIT_FOR bup_read_locked';
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "COMMIT%";
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "BACKUP DATABASE%";
-
-connection con4;
-
---echo con4: Activate synchronization point for BEGIN.
-SET DEBUG_SYNC= 'before_begin_trans SIGNAL begin_starting
-                 WAIT_FOR finish';
---echo con4: Starting begin -- will block on sync point
---echo Assumption (c): TRX not started is not included in backup
-send BEGIN;
-
-connection con5;
-
---echo con5: Wait for BEGIN to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR begin_starting';
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "BEGIN%";
-
---echo con5: Sending finish signal to wake them all.
-SET DEBUG_SYNC= 'now SIGNAL finish';
-
-# Reconnect to connections and fetch their results.
-
-connection con2;
-
---echo con2: Completing transaction
-  DELETE FROM bup_commit_blocker.t1 WHERE col_a LIKE '02%';
-COMMIT;
-
-connection con3;
-
---echo con3: Fetch COMMIT result
-reap;
-
-connection con4;
-
---echo con4: Fetch BEGIN result and completing transaction
-reap;
-  UPDATE bup_commit_blocker.t3 SET col_a = "con4: 05 CHANGED" WHERE col_a LIKE '05%';
-  UPDATE bup_commit_blocker.t3 SET col_a = "con4: 06 CHANGED" WHERE col_a LIKE '06%';
-COMMIT;
-
-connection con1;
-
---echo con1: Fetch BACKUP result
---replace_column 1 #
-reap;
-
-# Now restore the database and then check to make sure the new rows
-# were not backed up.
-
-# Do selects to show that all changes got applied.
---echo con1: Showing data after updates and backup
-SELECT * FROM bup_commit_blocker.t1;
-SELECT * FROM bup_commit_blocker.t2;
-SELECT * FROM bup_commit_blocker.t3;
-
---echo con1: Dropping the database
-DROP TABLE bup_commit_blocker.t1;
-DROP TABLE bup_commit_blocker.t2;
-DROP TABLE bup_commit_blocker.t3;
-
---echo con1: Restoring the database
---replace_column 1 #
- RESTORE FROM "bup_commit_blocker.bak";
-
---echo con1: Showing the data (no new data should be here).
-SELECT * FROM bup_commit_blocker.t1;
-SELECT * FROM bup_commit_blocker.t2;
-SELECT * FROM bup_commit_blocker.t3;
-
---echo
---echo Verifying test 1 results:
---echo
-
---echo T1 should not have the changes after backup - count(*) = 0
-SELECT count(*) FROM bup_commit_blocker.t1 WHERE col_a like 'con2%';
-
---echo T2 should have the changes after backup - count(*) = 2
-SELECT count(*) FROM bup_commit_blocker.t2 WHERE col_a like 'con3%';
-
---echo T3 should not have the changes after backup - count(*) = 0
-SELECT count(*) FROM bup_commit_blocker.t3 WHERE col_a like 'con4%';
-
---echo con1: Cleanup
-DROP DATABASE bup_commit_blocker;
-
-remove_file $MYSQLTEST_VARDIR/master-data/bup_commit_blocker.bak;
-SET DEBUG_SYNC= 'RESET';
-
-#
-# Test 2 - non-transactional statements only
-#
-
---echo 
---echo Starting Test 2
---echo 
-
-# Ingo: DELETE was disabled before converting the test from
-#       BACKUP_BREAKPOINT to DEBUG_SYNC. I left it disabled
-#       as an attempt to enable it made an infinite loop in
-#       write_table_data() in the loop:
-#    while (sch.prepare_count > 0)
-#    if (sch.step())
-#      goto error;
-#        sch.prepare_count did not change from being 1.
-#        When this is fixed, please remove this comment.
-
-#
-# Test 2 sequence diagram (not UML)
-#
-#   con1     con2     con3     con4     con5     con6       con7
-#  (setup)    |        |        |        |        |          |
-#     |       |        |        |        |        |          |
-#     |       |        |        |        |   #DELETE t4      |
-#     |       |        |        |   #show status  |          |
-#   BACKUP    |        |        |        |        |          |
-#     |       |        |        |    show status  |          |
-#     |       |        |        |        |        |       (results)
-#     |       |        |        |        |        |       UPDATE t5
-#     |       |        |        |    show status  |          |
-#   <...>     |        |        |        |      <...>      <...>
-# (results)   |        |        |        |        |          |
-#
-# Note: The resume of the commands is indicated with <...> and
-#       may occur in any order.
-#
-
-CREATE DATABASE bup_commit_blocker;
-
-# Create a non-transaction table and load it with data.
---echo con1: Creating tables
-#CREATE TABLE bup_commit_blocker.t4 (col_a int) ENGINE=MEMORY;
-CREATE TABLE bup_commit_blocker.t5 (col_a int) ENGINE=MEMORY;
-
---echo con1: Loading data
-#INSERT INTO bup_commit_blocker.t4 VALUES (1), (2), (3), (4), (5);
-INSERT INTO bup_commit_blocker.t5 VALUES (10), (20), (30), (40), (50);
-
---echo con1: Show that the new data doesn't exist before backup.
-#SELECT * FROM bup_commit_blocker.t4;
-SELECT * FROM bup_commit_blocker.t5;
-
-#connection con6;
-#
-#--echo con6: Activate synchronization point for DELETE.
-#SET DEBUG_SYNC= 'at_delete_end SIGNAL del_at_end WAIT_FOR finish';
-#--echo con6: Starting non-trx in progress -- will block with lock
-#--echo Assumption (d): non-TRX in progress is included in backup
-#send DELETE FROM bup_commit_blocker.t4 WHERE col_a <= 2;
-#
-#connection con5;
-#
-#--echo con5: Wait for DELETE to reach its synchronization point.
-#SET DEBUG_SYNC= 'now WAIT_FOR del_at_end';
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "DELETE%";
-
-connection con1;
-
---echo con1: Activate synchronization point for BACKUP.
-SET DEBUG_SYNC= 'before_backup_data_unlock SIGNAL bup_data_unlock
-                 WAIT_FOR finish';
---echo con1: Backing up database -- will block with lock
-send BACKUP DATABASE bup_commit_blocker TO "bup_commit_blocker.bak";
-
-connection con5;
-
---echo con5: Wait for BACKUP to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR bup_data_unlock';
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "BACKUP DATABASE%";
-
-connection con7;
-
---echo con7: Show that the statement in progress has executed before backup.
-#SELECT * FROM bup_commit_blocker.t4;
-SELECT * FROM bup_commit_blocker.t5;
-
---echo con7: Activate synchronization point for UPDATE.
-SET DEBUG_SYNC= 'wait_if_global_read_lock SIGNAL upd_read_lock';
---echo con7: Starting non-trx about to start
---echo Assumption (e): non-TRX not started is not included in backup
-send UPDATE bup_commit_blocker.t5 SET col_a = 333 WHERE col_a = 30;
-
-connection con5;
-
---echo con5: Wait for UPDATE to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR upd_read_lock';
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "UPDATE%";
-
---echo con5: Sending finish signal to wake them all.
-SET DEBUG_SYNC= 'now SIGNAL finish';
-
-# Reconnect to con6 and con7 and fetch their results.
-
-#connection con6;
-#
-#--echo con6: Fetch DELETE result
-#reap;
-
-connection con7;
-
---echo con7: Fetch UPDATE result
-reap;
-
-connection con1;
-
---echo con1: Fetch BACKUP result
---replace_column 1 #
-reap;
-
-# Now restore the database and then check to make sure the new rows
-# were not backed up.
-
-# Do selects to show that all changes got applied.
---echo con1: Showing data after updates and backup
-#SELECT * FROM bup_commit_blocker.t4;
-SELECT * FROM bup_commit_blocker.t5;
-
---echo con1: Dropping the database
-#DROP TABLE bup_commit_blocker.t4;
-DROP TABLE bup_commit_blocker.t5;
-
---echo con1: Restoring the database
---replace_column 1 #
- RESTORE FROM "bup_commit_blocker.bak";
-
---echo con1: Showing the data (no new data should be here).
-#SELECT * FROM bup_commit_blocker.t4;
-SELECT * FROM bup_commit_blocker.t5;
-
---echo
---echo Verifying test 2 results:
---echo
-
-#--echo T4 should have the changes after backup - count(*) = 3
-#SELECT count(*) FROM bup_commit_blocker.t4 WHERE col_a > 2;
-
---echo T5 should not have the changes after backup - count(*) = 0
-SELECT count(*) FROM bup_commit_blocker.t5 WHERE col_a = 333;
-
---echo con1: Cleanup
-DROP DATABASE bup_commit_blocker;
-
-remove_file $MYSQLTEST_VARDIR/master-data/bup_commit_blocker.bak;
-SET DEBUG_SYNC= 'RESET';
-
-#
-# Test 3 - mix of both transactional and non-transactional statements
-#
-
---echo 
---echo Starting Test 3
---echo 
-
-#
-# Test 3 sequence diagram (not UML)
-#
-#   con1     con2     con3     con4     con5     con6       con7
-#  (setup)    |        |        |        |        |          |
-#     |       |        |        |        |        |          |
-#     |     BEGIN      |        |        |        |          |
-#     |    UPDATE t1   |        |        |        |          |
-#     |       |      BEGIN      |        |        |          |
-#     |       |     INSERT t2   |        |        |          |
-#     |       |     INSERT t2   |        |        |          |
-#   BACKUP    |        |        |        |        |          |
-#     |       |        |        |        |    #INSERT t4     |
-#     |       |        |        |    show status  |          |
-#     |       |      COMMIT     |        |        |          |
-#     |       |        |        |    show status  |          |
-#     |       |        |      BEGIN      |        |          |
-#     |       |        |        |    show status  |          |
-#     |       |        |        |        |        |      (results)
-#     |       |        |        |        |        |       DELETE t5
-#     |       |        |        |    show status  |          |
-#     |       |        |        |     wake all    |          |
-#     |    DELETE t1   |        |        |        |          |
-#     |     COMMIT     |        |        |        |          |
-#     |       |      <...>      |        |        |          |
-#     |       |        |     UPDATE t3   |        |          |
-#     |       |        |     UPDATE t3   |        |          |
-#     |       |        |     COMMIT      |        |          |
-#   <...>     |        |        |        |      <...>      <...>
-# (results)   |        |        |        |        |          |
-#
-# Note: The resume of the commands is indicated with <...> and
-#       may occur in any order.
-#
-
-CREATE DATABASE bup_commit_blocker;
-
-# Create tables and load them with data.
---echo con1: Creating tables
-CREATE TABLE bup_commit_blocker.t1 (col_a CHAR(40)) ENGINE=INNODB;
-CREATE TABLE bup_commit_blocker.t2 (col_a CHAR(40)) ENGINE=INNODB;
-CREATE TABLE bup_commit_blocker.t3 (col_a CHAR(40)) ENGINE=INNODB;
-#CREATE TABLE bup_commit_blocker.t4 (col_a int) ENGINE=MEMORY;
-CREATE TABLE bup_commit_blocker.t5 (col_a int) ENGINE=MEMORY;
-
---echo con1: Loading data
-INSERT INTO bup_commit_blocker.t1 VALUES ("01 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("02 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("03 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("04 Some data to test");
-INSERT INTO bup_commit_blocker.t1 VALUES ("05 Some data to test");
-
-INSERT INTO bup_commit_blocker.t2 VALUES ("01 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("02 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("03 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("04 Some data to test");
-INSERT INTO bup_commit_blocker.t2 VALUES ("05 Some data to test");
-
-INSERT INTO bup_commit_blocker.t3 VALUES ("01 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("02 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("03 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("04 Some data to test");
-INSERT INTO bup_commit_blocker.t3 VALUES ("05 Some data to test");
-
-#INSERT INTO bup_commit_blocker.t4 VALUES (1), (2), (3), (4), (5);
-INSERT INTO bup_commit_blocker.t5 VALUES (10), (20), (30), (40), (50);
-
---echo con1: Show that the new data doesn't exist before backup.
-SELECT * FROM bup_commit_blocker.t1;
-SELECT * FROM bup_commit_blocker.t2;
-SELECT * FROM bup_commit_blocker.t3;
-#SELECT * FROM bup_commit_blocker.t4;
-SELECT * FROM bup_commit_blocker.t5;
-
-connection con2;
-
---echo con2: Get a transaction going and stop in the middle
---echo Assumption (a): TRX in progress is not included in backup
-BEGIN;
-  UPDATE bup_commit_blocker.t1 SET col_a = "con2: CHANGED" WHERE col_a LIKE '01%';
-
-connection con3;
-
---echo con3: Start a transaction and send commit after lock is taken
---echo Assumption (b): TRX in commit is included in backup
-BEGIN;
-  INSERT INTO bup_commit_blocker.t2 VALUES ("con3: 04 Some data to test");
-  INSERT INTO bup_commit_blocker.t2 VALUES ("con3: 05 Some data to test");
-
-connection con1;
-
-#
-# We must start the backup and allow it to gather the metadata first.
-# We stop (with a sync point) the backup after the metadata but before
-# the commit blocker.
-#
---echo con1: Activate synchronization points for BACKUP.
-# Before blocking commits, pause to show processlist state.
-# Before going to wait for the protection against global read lock to
-# disappear, signal about the wait, so that another thread can continue.
-# When COMMIT finishes, it releases the protection against global read lock,
-# which would allow BACKUP to continue while COMMIT also continues and
-# signals "commit_done". It is important that BACKUP does not run in
-# parallel and send another signal without waiting for the commit_done
-# signal to be processed. So BACKUP itself has to wait for that signal
-# after awaking and taking the global read lock. Only then BACKUP
-# can proceed and send a signal telling that it took the global read
-# lock. Unfortunately DEBUG_SYNC does not allow a sync point to emit a
-# signal after a wait_for action. So we need to send the signal in a later
-# sync point. For this test it is not important where this signal is sent,
-# as long as it is sent while BACKUP holds the global read lock.
-# Here we do it "before_backup_unblock_commit", where we have to
-# synchronize anyway.
-SET DEBUG_SYNC= 'before_commit_block SIGNAL bup_commit_block
-                 WAIT_FOR bup_go_read_lock';
-SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL bup_read_lock';
-SET DEBUG_SYNC= 'before_backup_data_lock WAIT_FOR commit_done';
-SET DEBUG_SYNC= 'before_backup_unblock_commit SIGNAL bup_read_locked
-                 WAIT_FOR finish';
---echo con1: Backing up database -- will block with lock
-send BACKUP DATABASE bup_commit_blocker TO "bup_commit_blocker.bak";
-
-#connection con6;
-#
-#--echo con6: Activate synchronization point for INSERT.
-#SET DEBUG_SYNC= 'after_insert_locked_tables SIGNAL insert_table_locked
-#                 WAIT_FOR finish';
-#--echo con6: Starting non-trx in progress -- will block
-#--echo Assumption (d): non-TRX in progress is included in backup
-#send INSERT INTO bup_commit_blocker.t4 VALUES (31), (32), (33);
-
-connection con5;
-
---echo con5: Wait for BACKUP to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR bup_commit_block';
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "BACKUP DATABASE%";
-
-#--echo con5: Wait for INSERT to reach its synchronization point.
-#SET DEBUG_SYNC= 'now WAIT_FOR insert_table_locked';
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "BACKUP DATABASE%";
-
-connection con3;
-
---echo con3: Activate synchronization points for COMMIT.
-SET DEBUG_SYNC= 'within_ha_commit_trans SIGNAL commit_read_locked
-                 WAIT_FOR commit_go_done';
-SET DEBUG_SYNC= 'after_commit SIGNAL commit_done WAIT_FOR finish';
---echo con3: Starting commit -- will block on sync point
-send COMMIT;
-
-connection con5;
-
---echo con5: Wait for COMMIT to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR commit_read_locked';
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "COMMIT%";
-
---echo con5: Let BACKUP run until the next sync point.
-SET DEBUG_SYNC= 'now SIGNAL bup_go_read_lock WAIT_FOR bup_read_lock';
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "BACKUP DATABASE%";
-
---echo con5: Let COMMIT continue until the sync point at its end.
---echo con5: The completed COMMIT implicitly wakes BACKUP.
---echo con5: So wait for BACKUP to reach the next synchronization point.
-SET DEBUG_SYNC= 'now SIGNAL commit_go_done WAIT_FOR bup_read_locked';
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "COMMIT%";
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "BACKUP DATABASE%";
-
-connection con4;
-
---echo con4: Activate synchronization point for BEGIN.
-SET DEBUG_SYNC= 'before_begin_trans SIGNAL begin_starting
-                 WAIT_FOR finish';
---echo con4: Starting begin -- will block with lock
---echo Assumption (c): TRX not started is not included in backup
-send BEGIN;
-
-connection con5;
-
---echo con5: Wait for BEGIN to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR begin_starting';
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "BEGIN%";
-
-connection con7;
-
---echo con7: Show that the statement in progress has executed before backup.
-#SELECT * FROM bup_commit_blocker.t4;
-SELECT * FROM bup_commit_blocker.t5;
-
---echo con7: Activate synchronization point for DELETE.
-SET DEBUG_SYNC= 'wait_if_global_read_lock SIGNAL del_read_lock';
---echo con7: Starting non-trx about to start -- will block with lock
---echo Assumption (e): non-TRX not started is not included in backup
-send DELETE FROM bup_commit_blocker.t5 WHERE col_a = 50;
-
-connection con5;
-
---echo con5: Wait for DELETE to reach its synchronization point.
-SET DEBUG_SYNC= 'now WAIT_FOR del_read_lock';
-#SELECT state, info FROM
-#INFORMATION_SCHEMA.PROCESSLIST
-#WHERE info LIKE "DELETE%";
-
---echo con5: Sending finish signal to wake them all.
-SET DEBUG_SYNC= 'now SIGNAL finish';
-
-# Reconnect to con2, con3, con4, con6, and con7 and fetch their results.
-
-connection con2;
-
---echo con2: Completing transaction
-  DELETE FROM bup_commit_blocker.t2 WHERE col_a LIKE '02%';
-COMMIT;
-
-connection con3;
-
---echo con3: Fetch COMMIT result
-reap;
-
-connection con4;
-
---echo con4: Fetch BEGIN result and completing transaction
-reap;
-  UPDATE bup_commit_blocker.t3 SET col_a = "con4: 05 CHANGED" WHERE col_a LIKE '05%';
-  UPDATE bup_commit_blocker.t3 SET col_a = "con4: 06 CHANGED" WHERE col_a LIKE '06%';
-COMMIT;
-
-connection con6;
-
-#--echo con6: Fetch INSERT result
-#reap;
-
-connection con7;
-
---echo con7: Fetch DELETE result
-reap;
-
-connection con1;
-
---echo con1: Fetch BACKUP result
---replace_column 1 #
-reap;
-
-# Now restore the database and then check to make sure the new rows
-# were not backed up.
-
-# Do selects to show that all changes got applied.
---echo con1: Showing data after updates and backup
-SELECT * FROM bup_commit_blocker.t1;
-SELECT * FROM bup_commit_blocker.t2;
-SELECT * FROM bup_commit_blocker.t3;
-#SELECT * FROM bup_commit_blocker.t4;
-SELECT * FROM bup_commit_blocker.t5;
-
---echo con1: Dropping the database
-DROP TABLE bup_commit_blocker.t1;
-DROP TABLE bup_commit_blocker.t2;
-DROP TABLE bup_commit_blocker.t3;
-#DROP TABLE bup_commit_blocker.t4;
-DROP TABLE bup_commit_blocker.t5;
-
---echo con1: Restoring the database
---replace_column 1 #
-RESTORE FROM "bup_commit_blocker.bak";
-
---echo con1: Showing the data (no new data should be here).
-SELECT * FROM bup_commit_blocker.t1;
-SELECT * FROM bup_commit_blocker.t2;
-SELECT * FROM bup_commit_blocker.t3;
-#SELECT * FROM bup_commit_blocker.t4;
-SELECT * FROM bup_commit_blocker.t5;
-
---echo
---echo Verifying test 3 results:
---echo
-
---echo T1 should not have the changes after backup - count(*) = 0
-SELECT count(*) FROM bup_commit_blocker.t1 WHERE col_a like 'con2%';
-
---echo T2 should have the changes after backup - count(*) = 2
-SELECT count(*) FROM bup_commit_blocker.t2 WHERE col_a like 'con3%';
-
---echo T3 should not have the changes after backup - count(*) = 0
-SELECT count(*) FROM bup_commit_blocker.t3 WHERE col_a like 'con4%';
-
-#--echo T4 should have the changes after backup - count(*) = 3
-#SELECT count(*) FROM bup_commit_blocker.t4 WHERE col_a > 30;
-
---echo T5 should not have the changes after backup - count(*) = 1
-SELECT count(*) FROM bup_commit_blocker.t5 WHERE col_a >= 50;
-
---echo con1: Cleanup
-DROP DATABASE bup_commit_blocker;
-
-remove_file $MYSQLTEST_VARDIR/master-data/bup_commit_blocker.bak;
-SET DEBUG_SYNC= 'RESET';
-

=== modified file 'mysql-test/suite/backup/t/backup_commit_restore.test'
--- a/mysql-test/suite/backup/t/backup_commit_restore.test	2008-10-23 08:13:54 +0000
+++ b/mysql-test/suite/backup/t/backup_commit_restore.test	2008-11-17 09:57:51 +0000
@@ -20,7 +20,7 @@ replace_column 1 #;
 BACKUP DATABASE commit_test TO '81';
 
 replace_column 1 #;
-RESTORE FROM '81';
+RESTORE FROM '81' OVERWRITE;
 
 SELECT * FROM t1;
 ROLLBACK;
@@ -37,7 +37,7 @@ replace_column 1 #;
 BACKUP DATABASE commit_test TO '82';
 
 replace_column 1 #;
-RESTORE FROM '82';
+RESTORE FROM '82' OVERWRITE;
 
 SELECT * FROM t1;
 SELECT * FROM t2;
@@ -58,7 +58,7 @@ replace_column 1 #;
 BACKUP DATABASE commit_test TO '83';
 
 replace_column 1 #;
-RESTORE FROM '83';
+RESTORE FROM '83' OVERWRITE;
 
 SELECT * FROM t1;
 SELECT * FROM t2;
@@ -81,7 +81,7 @@ replace_column 1 #;
 BACKUP DATABASE commit_test TO '84';
 
 replace_column 1 #;
-RESTORE FROM '84';
+RESTORE FROM '84' OVERWRITE;
 
 SELECT * FROM t1;
 SELECT * FROM t2;
@@ -106,7 +106,7 @@ replace_column 1 #;
 BACKUP DATABASE commit_test TO '85';
 
 replace_column 1 #;
-RESTORE FROM '85';
+RESTORE FROM '85' OVERWRITE;
 
 SELECT * FROM t1;
 SELECT * FROM t2;
@@ -133,7 +133,7 @@ BACKUP DATABASE commit_test TO '86';
 
 SET @@autocommit=0;
 replace_column 1 #;
-RESTORE FROM '86';
+RESTORE FROM '86' OVERWRITE;
 
 #Test of scenario from BUG#34205
 DROP TABLE t5;
@@ -162,7 +162,7 @@ BACKUP DATABASE commit_test TO '87';
 
 SET @@autocommit=1;
 replace_column 1 #;
-RESTORE FROM '87';
+RESTORE FROM '87' OVERWRITE;
 
 SELECT * FROM t1;
 SELECT * FROM t2;

=== modified file 'mysql-test/suite/backup/t/backup_compression.test'
--- a/mysql-test/suite/backup/t/backup_compression.test	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_compression.test	2008-11-17 09:57:51 +0000
@@ -12,11 +12,11 @@ replace_column 1 #;
 BACKUP DATABASE db1 TO 'db2.bak.gz' WITH COMPRESSION COMPRESSION_ALGORITHM=gzip;
 
 replace_column 1 #;
-RESTORE FROM 'db1.bak.gz';
+RESTORE FROM 'db1.bak.gz' OVERWRITE;
 SHOW TABLES FROM db1;
 
 replace_column 1 #;
-RESTORE FROM 'db2.bak.gz';
+RESTORE FROM 'db2.bak.gz' OVERWRITE;
 SHOW TABLES FROM db1;
 
 DROP DATABASE db1;

=== modified file 'mysql-test/suite/backup/t/backup_concurrent.test'
--- a/mysql-test/suite/backup/t/backup_concurrent.test	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_concurrent.test	2008-11-17 09:57:51 +0000
@@ -79,7 +79,7 @@ reap;
 --echo ---------------------------------------------------
 --echo Starting restore
 SET DEBUG_SYNC= 'after_backup_start_restore SIGNAL running WAIT_FOR restore';
-send RESTORE FROM 'backup1';
+send RESTORE FROM 'backup1' OVERWRITE;
 
 connection default;
 --echo Waiting for restore to get going

=== modified file 'mysql-test/suite/backup/t/backup_db_grants.test'
--- a/mysql-test/suite/backup/t/backup_db_grants.test	2008-11-19 16:32:01 +0000
+++ b/mysql-test/suite/backup/t/backup_db_grants.test	2008-12-04 23:14:30 +0000
@@ -65,7 +65,7 @@ SHOW GRANTS FOR 'no_user'@'%';
 
 --echo Run Restore
 --replace_column 1 #
-RESTORE FROM 'bup_db_grants.bak';
+RESTORE FROM 'bup_db_grants.bak' OVERWRITE;
 
 SHOW TABLES FROM bup_db_grants;
 
@@ -92,7 +92,7 @@ CREATE USER 'bup_user1'@'nosuchhost';
 
 --echo Run Restore
 --replace_column 1 #
-RESTORE FROM 'bup_db_grants.bak';
+RESTORE FROM 'bup_db_grants.bak' OVERWRITE;
 
 SHOW TABLES FROM bup_db_grants;
 
@@ -180,7 +180,7 @@ EXECUTE stmt3;
 
 --echo Run restore.
 --replace_column 1 #
-RESTORE FROM 'bup_db_grants.bak';
+RESTORE FROM 'bup_db_grants.bak' OVERWRITE;
 
 FLUSH PRIVILEGES;
 

=== modified file 'mysql-test/suite/backup/t/backup_ddl_blocker.test'
--- a/mysql-test/suite/backup/t/backup_ddl_blocker.test	2008-10-24 08:25:48 +0000
+++ b/mysql-test/suite/backup/t/backup_ddl_blocker.test	2008-11-20 14:07:23 +0000
@@ -243,7 +243,7 @@ DROP TABLE bup_ddl_blocker.t1, bup_ddl_b
 
 --echo con1: Restoring the database
 --replace_column 1 #
-RESTORE FROM "bup_ddl_blocker.bak";
+RESTORE FROM "bup_ddl_blocker.bak" OVERWRITE;
 
 --echo con1: Showing columns that were backed up
 
@@ -297,7 +297,7 @@ SET DEBUG_SYNC= 'now WAIT_FOR con3_start
 SET DEBUG_SYNC= 'before_block_ddl SIGNAL bup_blocked WAIT_FOR status_shown';
 SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_started WAIT_FOR status_shown2';
 --echo con1: Restoring database -- will block with lock
-send RESTORE FROM "bup_ddl_blocker_orig.bak";
+send RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE;
 
 connection con6;
 
@@ -514,7 +514,7 @@ DROP TABLE bup_ddl_blocker.t01, bup_ddl_
 
 --echo con1: Restoring the database
 --replace_column 1 #
-RESTORE FROM "bup_ddl_blocker.bak";
+RESTORE FROM "bup_ddl_blocker.bak" OVERWRITE;
 
 --echo con1: Showing columns that were backed up
 --echo con1: Table t01 should be in restore
@@ -564,7 +564,7 @@ SET DEBUG_SYNC= 'now WAIT_FOR con3_start
 SET DEBUG_SYNC= 'before_block_ddl SIGNAL bup_blocked WAIT_FOR status_shown';
 SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_started WAIT_FOR status_shown2';
 --echo con1: Restoring database -- will block with lock
-send RESTORE FROM "bup_ddl_blocker_orig.bak";
+send RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE;
 
 connection con6;
 
@@ -774,7 +774,7 @@ DROP TABLE bup_ddl_blocker.t1, bup_ddl_b
 
 --echo con1: Restoring the database
 --replace_column 1 #
-RESTORE FROM "bup_ddl_blocker.bak";
+RESTORE FROM "bup_ddl_blocker.bak" OVERWRITE;
 
 --echo con1: Showing columns that were backed up
 --echo con1: Table t2 should not be in restore
@@ -823,7 +823,7 @@ SET DEBUG_SYNC= 'now WAIT_FOR con3_start
 SET DEBUG_SYNC= 'before_block_ddl SIGNAL bup_blocked WAIT_FOR status_shown';
 SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_started WAIT_FOR status_shown2';
 --echo con1: Restoring database -- will block with lock
-send RESTORE FROM "bup_ddl_blocker_orig.bak";
+send RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE;
 
 connection con6;
 
@@ -1061,7 +1061,7 @@ DROP DATABASE bup_ddl_blocker_3;
 --echo con1: Restoring the database
 --replace_column 1 #
 --disable_warnings
-RESTORE FROM "bup_ddl_blocker.bak";
+RESTORE FROM "bup_ddl_blocker.bak" OVERWRITE;
 --enable_warnings
 
 --echo con1: Showing databases that were backed up
@@ -1137,7 +1137,7 @@ SET DEBUG_SYNC= 'now WAIT_FOR con3_start
 SET DEBUG_SYNC= 'before_block_ddl SIGNAL bup_blocked WAIT_FOR status_shown';
 SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_started WAIT_FOR status_shown2';
 --echo con1: Restoring database -- will block with lock
-send RESTORE FROM "bup_ddl_blocker_orig.bak";
+send RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE;
 
 connection con6;
 
@@ -1381,7 +1381,7 @@ DROP DATABASE bup_ddl_blocker_4;
 
 --echo con1: Restoring the database
 --replace_column 1 #
-RESTORE FROM "bup_ddl_blocker.bak";
+RESTORE FROM "bup_ddl_blocker.bak" OVERWRITE;
 
 --echo con1: Showing databases that were backed up
 --echo con1: bup_ddl_blocker_1 has been renamed and
@@ -1465,7 +1465,7 @@ SET DEBUG_SYNC= 'now WAIT_FOR con3_start
 SET DEBUG_SYNC= 'before_block_ddl SIGNAL bup_blocked WAIT_FOR status_shown';
 SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_started WAIT_FOR status_shown2';
 --echo con1: Restoring database -- will block with lock
-send RESTORE FROM "bup_ddl_blocker_orig.bak";
+send RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE;
 
 connection con6;
 
@@ -1732,7 +1732,7 @@ DROP DATABASE bup_ddl_blocker_4;
 --echo con1: Restoring the database
 --replace_column 1 #
 --disable_warnings
-RESTORE FROM "bup_ddl_blocker.bak";
+RESTORE FROM "bup_ddl_blocker.bak" OVERWRITE;
 --enable_warnings
 
 --echo con1: Showing databases that were backed up
@@ -1829,7 +1829,7 @@ SET DEBUG_SYNC= 'now WAIT_FOR con3_start
 SET DEBUG_SYNC= 'before_block_ddl SIGNAL bup_blocked WAIT_FOR status_shown';
 SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_started WAIT_FOR status_shown2';
 --echo con1: Restoring database -- will block with lock
-send RESTORE FROM "bup_ddl_blocker_orig.bak";
+send RESTORE FROM "bup_ddl_blocker_orig.bak" OVERWRITE;
 
 connection con6;
 

=== modified file 'mysql-test/suite/backup/t/backup_errors.test'
--- a/mysql-test/suite/backup/t/backup_errors.test	2008-11-19 16:32:01 +0000
+++ b/mysql-test/suite/backup/t/backup_errors.test	2008-12-04 23:14:30 +0000
@@ -50,6 +50,10 @@ BACKUP DATABASE foo TO 'test.bak';
 -- error ER_BAD_DB_ERROR
 BACKUP DATABASE test,foo,bdb,bar TO 'test.bak';
 
+# repeated database
+-- error ER_NONUNIQ_DB
+BACKUP DATABASE foo,test,bar,foo TO 'test.bak';
+
 # Test that BACKUP/RESTORE statements are disable inside stored routines,
 # triggers and events.
 
@@ -290,3 +294,54 @@ DROP DATABASE db1;
 
 --echo
 --echo Done testing for Bug#38624
+
+
+--echo 
+--echo Testing RESTORE ... OVERWRITE functionality
+--echo See bug#34579
+--echo
+
+--source include/not_embedded.inc
+
+--echo Initialize
+CREATE DATABASE db1;
+USE db1;
+CREATE TABLE table1 (text VARCHAR(20));
+INSERT INTO table1 VALUES ('Inserted before');
+
+--echo 
+--echo Backup database
+--replace_column 1 #
+BACKUP DATABASE db1 TO 'overwrite.bak';
+
+--echo 
+--echo Insert more data and display
+INSERT INTO table1 VALUES ('Inserted after');
+SELECT * FROM table1;
+
+--echo 
+--echo Restore without OVERWRITE flag; will fail
+--error ER_RESTORE_DB_EXISTS
+RESTORE FROM 'overwrite.bak';
+
+--echo 
+--echo Restore with OVERWRITE flag; will succeed
+--replace_column 1 #
+RESTORE FROM 'overwrite.bak' OVERWRITE;
+
+--echo 
+--echo Show that inserted value 2 is not there
+SELECT * FROM table1;
+
+DROP DATABASE db1;
+
+--echo 
+--echo Restore after deleting db; will succeed
+--replace_column 1 #
+RESTORE FROM 'overwrite.bak';
+
+--echo 
+--echo Show that inserted value 2 is not there
+SELECT * FROM table1;
+
+DROP DATABASE db1;

=== modified file 'mysql-test/suite/backup/t/backup_fkey.test'
--- a/mysql-test/suite/backup/t/backup_fkey.test	2008-10-24 08:25:48 +0000
+++ b/mysql-test/suite/backup/t/backup_fkey.test	2008-11-17 09:57:51 +0000
@@ -79,12 +79,12 @@ SHOW VARIABLES LIKE 'foreign_key_checks%
 # Restore the database and ensure there are no errors.
 --echo Now restore the database.
 --replace_column 1 #
-RESTORE FROM 'backup_fkey.bak';
+RESTORE FROM 'backup_fkey.bak' OVERWRITE;
 
 # Now restore the original files to show there are no problems
 # restoring valid fkey relationships.
 --replace_column 1 #
-RESTORE FROM 'backup_fkey_orig.bak';
+RESTORE FROM 'backup_fkey_orig.bak' OVERWRITE;
 
 --echo Show data
 SELECT * FROM backup_fkey.parent;
@@ -120,7 +120,7 @@ SHOW VARIABLES LIKE 'foreign_key_checks%
 
 --echo Restoring data
 --replace_column 1 #
-RESTORE FROM 'backup_fkey.bak';
+RESTORE FROM 'backup_fkey.bak' OVERWRITE;
 
 --echo Verify foreign_key_checks = ON
 SHOW VARIABLES LIKE 'foreign_key_checks%';
@@ -131,7 +131,7 @@ SHOW VARIABLES LIKE 'foreign_key_checks%
 
 --echo Restoring data
 --replace_column 1 #
-RESTORE FROM 'backup_fkey.bak';
+RESTORE FROM 'backup_fkey.bak' OVERWRITE;
 
 --echo Verify foreign_key_checks = OFF
 SHOW VARIABLES LIKE 'foreign_key_checks%';

=== modified file 'mysql-test/suite/backup/t/backup_lock_myisam.test'
--- a/mysql-test/suite/backup/t/backup_lock_myisam.test	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_lock_myisam.test	2008-11-17 09:57:51 +0000
@@ -98,7 +98,7 @@ DROP DATABASE db1;
 --echo now start the restore and while the restore is running, fire the trigger
 --echo activate synchronization points for restore.
 SET DEBUG_SYNC= 'restore_in_progress SIGNAL wait_for_restore WAIT_FOR finish';
---send RESTORE FROM 'db1.bak'
+--send RESTORE FROM 'db1.bak' OVERWRITE;
 
 --echo From breakpoints:
 --connection breakpoints
@@ -147,7 +147,7 @@ DELETE FROM db2.t2;
 --echo now start the restore and while the restore is running, fire the trigger
 --echo activate synchronization points for restore.
 SET DEBUG_SYNC= 'restore_in_progress SIGNAL wait_for_restore WAIT_FOR finish';
---send RESTORE FROM 'db1.bak'
+--send RESTORE FROM 'db1.bak' OVERWRITE;
 
 --echo From breakpoints:
 --connection breakpoints

=== modified file 'mysql-test/suite/backup/t/backup_logs.test'
--- a/mysql-test/suite/backup/t/backup_logs.test	2008-10-15 20:00:48 +0000
+++ b/mysql-test/suite/backup/t/backup_logs.test	2008-11-17 09:57:51 +0000
@@ -44,6 +44,8 @@ DROP DATABASE IF EXISTS backup_logs;
 --remove_file $MYSQLTEST_VARDIR/master-data/backup_logs_orig.bak;
 --enable_warnings
 
+PURGE BACKUP LOGS;
+
 connect (con1,localhost,root,,);
 connect (con2,localhost,root,,);
 
@@ -60,7 +62,6 @@ CREATE DATABASE backup_logs;
 CREATE TABLE backup_logs.t1 (a char(30)) ENGINE=MYISAM;
 CREATE TABLE backup_logs.t2 (a char(30)) ENGINE=INNODB;
 CREATE TABLE backup_logs.t3 (a char(30)) ENGINE=MEMORY;
-CREATE TABLE backup_logs.t1_res (id BIGINT UNSIGNED NOT NULL) ENGINE=MEMORY;
 
 INSERT INTO backup_logs.t1 VALUES ("01 Test #1 - progress"); 
 INSERT INTO backup_logs.t1 VALUES ("02 Test #1 - progress"); 
@@ -92,7 +93,11 @@ SET DEBUG_SYNC= 'after_backup_start_back
 SET DEBUG_SYNC= 'after_backup_validated    SIGNAL validated WAIT_FOR do_phase2';
 SET DEBUG_SYNC= 'after_backup_binlog       SIGNAL phase2    WAIT_FOR finish';
 
---echo con2: Send backup command.
+--echo Start using a known backup id for a more definitive test.
+SET SESSION debug="+d,set_backup_id";
+
+--echo con2: Send backup command. 
+--echo con2: Backup id = 500.
 send BACKUP DATABASE backup_logs to 'backup_logs_orig.bak';
 
 connection con1;
@@ -101,46 +106,46 @@ connection con1;
 SET DEBUG_SYNC= 'now WAIT_FOR started';
 
 --echo con1: Display progress
-SELECT MAX(backup_id) INTO @bup_id FROM mysql.backup_progress;
-INSERT INTO backup_logs.t1_res (id) VALUES (@bup_id);
-SELECT notes FROM mysql.backup_progress AS ob JOIN backup_logs.t1_res as t1 ON ob.backup_id = t1.id;
+SELECT notes FROM mysql.backup_progress WHERE backup_id = 500;
 
 --echo con1: Let backup step to running state.
 SET DEBUG_SYNC= 'now SIGNAL do_run WAIT_FOR phase1';
 
 --echo con1: Display progress
-SELECT notes FROM mysql.backup_progress AS ob JOIN backup_logs.t1_res as t1 ON ob.backup_id = t1.id;
+SELECT notes FROM mysql.backup_progress WHERE backup_id = 500;
 
 --echo con1: Let backup do the backup phase1.
 SET DEBUG_SYNC= 'now SIGNAL backup WAIT_FOR validated';
 
 --echo con1: Display progress
-SELECT notes FROM mysql.backup_progress AS ob JOIN backup_logs.t1_res as t1 ON ob.backup_id = t1.id;
+SELECT notes FROM mysql.backup_progress WHERE backup_id = 500;
 
 --echo con1: Let backup do the backup phase2.
 SET DEBUG_SYNC= 'now SIGNAL do_phase2 WAIT_FOR phase2';
 
 --echo con1: Display progress
-SELECT notes FROM mysql.backup_progress AS ob JOIN backup_logs.t1_res as t1 ON ob.backup_id = t1.id;
+SELECT notes FROM mysql.backup_progress WHERE backup_id = 500;
 
 --echo con1: Let backup finish.
 SET DEBUG_SYNC= 'now SIGNAL finish';
 
 connection con2;
 --echo con2: Finish backup command
---replace_column 1 #
 reap;
 
+FLUSH BACKUP LOGS;
+
+--echo Turn off debugging session.
+SET SESSION debug="-d";
+
 connection con1;
 
 #Show results
 --replace_column 1 # 2 # 3 # 4 # 10 # 11 # 12 # 15 # 16 #
---query_vertical SELECT ob.* FROM mysql.backup_history AS ob JOIN backup_logs.t1_res AS t1 ON ob.backup_id = t1.id;
+--query_vertical SELECT * FROM mysql.backup_history WHERE backup_id = 500;
 --replace_column 1 # 3 # 4 #
-SELECT obp.* FROM mysql.backup_progress AS obp JOIN backup_logs.t1_res AS t1 ON obp.backup_id = t1.id;
+SELECT * FROM mysql.backup_progress WHERE backup_id = 500;
 
-DELETE FROM backup_logs.t1_res;
- 
 connection con2;
 
 --echo con2: Activate sync points for the backup statement.
@@ -148,7 +153,8 @@ SET DEBUG_SYNC= 'after_backup_log_init  
 SET DEBUG_SYNC= 'after_backup_start_restore SIGNAL running WAIT_FOR finish';
 
 --echo con2: Send restore command.
-send RESTORE FROM 'backup_logs_orig.bak';
+--echo con2: Backup id = 501.
+send RESTORE FROM 'backup_logs_orig.bak' OVERWRITE;
 
 connection con1;
 
@@ -156,25 +162,23 @@ connection con1;
 SET DEBUG_SYNC= 'now WAIT_FOR started';
 
 --echo con1: Display progress
-select * from backup_logs.t1_res;
-SELECT MAX(backup_id) INTO @bup_id FROM mysql.backup_progress;
-INSERT INTO backup_logs.t1_res (id) VALUES (@bup_id);
-SELECT notes FROM mysql.backup_progress AS ob JOIN backup_logs.t1_res as t1 ON ob.backup_id = t1.id;
+SELECT notes FROM mysql.backup_progress WHERE backup_id = 501;
 
 --echo con1: Let restore step to running state.
 SET DEBUG_SYNC= 'now SIGNAL do_run WAIT_FOR running';
 
 --echo con1: Display progress
-SELECT notes FROM mysql.backup_progress AS ob JOIN backup_logs.t1_res as t1 ON ob.backup_id = t1.id;
+SELECT notes FROM mysql.backup_progress WHERE backup_id = 501;
 
 --echo con1: Let restore do its job and finish.
 SET DEBUG_SYNC= 'now SIGNAL finish';
 
 connection con2;
 --echo con2: Finish restore command
---replace_column 1 #
 reap;
 
+FLUSH BACKUP LOGS;
+
 SET DEBUG_SYNC= 'now SIGNAL complete';
 
 connection con1;
@@ -182,41 +186,27 @@ connection con1;
 SET DEBUG_SYNC= 'now WAIT_FOR complete';
 
 #Show results
-DELETE FROM backup_logs.t1_res;
-SELECT MAX(backup_id) INTO @bup_id FROM mysql.backup_history WHERE command LIKE "RESTORE FROM%";
-INSERT INTO backup_logs.t1_res (id) VALUES (@bup_id);
 --replace_column 1 # 2 # 3 # 4 # 10 # 11 # 12 # 15 # 16 #
---query_vertical SELECT ob.* FROM mysql.backup_history AS ob JOIN backup_logs.t1_res AS t1 ON ob.backup_id = t1.id;
+--query_vertical SELECT * FROM mysql.backup_history WHERE backup_id = 501;
 --replace_column 1 # 3 # 4 #
-SELECT obp.* FROM mysql.backup_progress AS obp JOIN backup_logs.t1_res AS t1 ON obp.backup_id = t1.id;
+SELECT * FROM mysql.backup_progress WHERE backup_id = 501;
 
 SET DEBUG_SYNC= 'RESET';
 
-#
-# Now test read of backupid with known id using debug insertion
-#
-SET SESSION debug="d,set_backup_id";
-
 --remove_file $MYSQLTEST_VARDIR/master-data/backup_logs_orig.bak
-
-#
-# The first backup will cause the value to be set to 500 and written to file.
-# The second backup will read the value (500) and increment it.
-#--replace_column 1 #
+--echo The backup id for this command should be 502.
 BACKUP DATABASE backup_logs to 'backup_logs_orig.bak';
 
-SET SESSION debug="d";
-
 --remove_file $MYSQLTEST_VARDIR/master-data/backup_logs_orig.bak
---echo The backup id for this command should be 501.
+--echo The backup id for this command should be 503.
 BACKUP DATABASE backup_logs to 'backup_logs_orig.bak';
 
 --remove_file $MYSQLTEST_VARDIR/master-data/backup_logs_orig.bak
---echo The backup id for this command should be 502.
+--echo The backup id for this command should be 504.
 BACKUP DATABASE backup_logs to 'backup_logs_orig.bak';
 
 --remove_file $MYSQLTEST_VARDIR/master-data/backup_logs_orig.bak
---echo The backup id for this command should be 503.
+--echo The backup id for this command should be 505.
 BACKUP DATABASE backup_logs to 'backup_logs_orig.bak';
 
 #

=== added file 'mysql-test/suite/backup/t/backup_logs_output-master.opt'
--- a/mysql-test/suite/backup/t/backup_logs_output-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_logs_output-master.opt	2008-11-17 11:17:59 +0000
@@ -0,0 +1 @@
+--backup_history_log_file=$MYSQLTEST_VARDIR/master-data/history.txt --backup_progress_log_file=$MYSQLTEST_VARDIR/master-data/progress.txt --log-backup-output

=== modified file 'mysql-test/suite/backup/t/backup_logs_output.test'
--- a/mysql-test/suite/backup/t/backup_logs_output.test	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_logs_output.test	2008-11-10 16:49:10 +0000
@@ -11,7 +11,34 @@ connect (con1,localhost,root,,,,);
 --echo con1
 connection con1;
 
---echo Display backup variables
+--echo Clear the logs.
+SET @@global.backup_history_log = 'ON';
+SET @@global.backup_progress_log = 'ON';
+
+#
+# BUG#40219 No startup options for backup_*_logname.
+#
+--echo Display backup variable values from startup options file.
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+SHOW VARIABLES LIKE 'backup_history%';
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+SHOW VARIABLES LIKE 'backup_progress%';
+SHOW VARIABLES LIKE 'log_backup_output';
+
+--echo Set the backup log file names to default values.
+SET @@global.backup_history_log_file = DEFAULT;
+SET @@global.backup_progress_log_file = DEFAULT;
+SET @@global.log_backup_output = 'TABLE';
+
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+
+--echo See that the log names have been reset.
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+SHOW VARIABLES LIKE 'backup_history%';
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+SHOW VARIABLES LIKE 'backup_progress%';
+
 SHOW VARIABLES LIKE 'backup_history_log';
 SHOW VARIABLES LIKE 'backup_progress_log';
 SHOW VARIABLES LIKE 'log_backup_output';
@@ -28,9 +55,6 @@ SHOW VARIABLES LIKE 'backup_history_log'
 SHOW VARIABLES LIKE 'backup_progress_log';
 SHOW VARIABLES LIKE 'log_backup_output';
 
-TRUNCATE TABLE mysql.backup_history;
-TRUNCATE TABLE mysql.backup_progress;
-
 --echo Show the size of the logs
 SELECT count(*) FROM mysql.backup_history;
 SELECT count(*) FROM mysql.backup_progress;
@@ -71,8 +95,8 @@ SHOW VARIABLES LIKE 'backup_history_log'
 SHOW VARIABLES LIKE 'backup_progress_log';
 SHOW VARIABLES LIKE 'log_backup_output';
 
-TRUNCATE TABLE mysql.backup_history;
-TRUNCATE TABLE mysql.backup_progress;
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
 
 --replace_column 1 #
 BACKUP DATABASE bup_log TO 'bup_log.bak';
@@ -91,6 +115,12 @@ FLUSH BACKUP LOGS;
 --echo '---Checking backup logs when log_backup_output is TABLE---'
 --echo '---and the progress log is turned off                   ---'
 
+--echo Clear the logs.
+SET @@global.backup_history_log = 'ON';
+SET @@global.backup_progress_log = 'ON';
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+
 SET @@global.backup_history_log = 'ON';
 SET @@global.backup_progress_log = 'OFF';
 
@@ -99,9 +129,6 @@ SHOW VARIABLES LIKE 'backup_history_log'
 SHOW VARIABLES LIKE 'backup_progress_log';
 SHOW VARIABLES LIKE 'log_backup_output';
 
-TRUNCATE TABLE mysql.backup_history;
-TRUNCATE TABLE mysql.backup_progress;
-
 --echo Show the size of the logs
 SELECT count(*) FROM mysql.backup_history;
 SELECT count(*) FROM mysql.backup_progress;
@@ -123,6 +150,12 @@ FLUSH BACKUP LOGS;
 --echo '---Checking backup logs when log_backup_output is TABLE---'
 --echo '---and the history log is turned off                 ---'
 
+--echo Clear the logs.
+SET @@global.backup_history_log = 'ON';
+SET @@global.backup_progress_log = 'ON';
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+
 SET @@global.backup_history_log = 'OFF';
 SET @@global.backup_progress_log = 'ON';
 
@@ -131,9 +164,6 @@ SHOW VARIABLES LIKE 'backup_history_log'
 SHOW VARIABLES LIKE 'backup_progress_log';
 SHOW VARIABLES LIKE 'log_backup_output';
 
-TRUNCATE TABLE mysql.backup_history;
-TRUNCATE TABLE mysql.backup_progress;
-
 --echo Show the size of the logs
 SELECT count(*) FROM mysql.backup_history;
 SELECT count(*) FROM mysql.backup_progress;
@@ -146,6 +176,12 @@ SELECT count(*) FROM mysql.backup_histor
 SELECT count(*) FROM mysql.backup_progress;
 
 FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+
+--echo Show the size of the logs
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
 --file_exists $MYSQLTEST_VARDIR/master-data/backup_history.log
 --file_exists $MYSQLTEST_VARDIR/master-data/backup_progress.log
 
@@ -165,15 +201,6 @@ SHOW VARIABLES LIKE 'backup_history_log'
 SHOW VARIABLES LIKE 'backup_progress_log';
 SHOW VARIABLES LIKE 'log_backup_output';
 
-TRUNCATE TABLE mysql.backup_history;
-TRUNCATE TABLE mysql.backup_progress;
-
-#
-# BUG#33364 - uncomment when purge command is implemented
-#
-# Purge the backup logs
-#PURGE BACKUP LOGS;
-
 --replace_column 1 #
 BACKUP DATABASE bup_log TO 'bup_log.bak';
 
@@ -182,12 +209,11 @@ SELECT count(*) FROM mysql.backup_histor
 SELECT count(*) FROM mysql.backup_progress;
 
 FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+
 --file_exists $MYSQLTEST_VARDIR/master-data/backup_history.log
 --file_exists $MYSQLTEST_VARDIR/master-data/backup_progress.log
 
-#
-# BUG#33364 - uncomment when purge command is implemented
-#
 # Check contents of logs for data. 
 #--error 0
 #--exec grep -q "BACKUP DATABASE bup_log TO 'bup_log.bak'" $MYSQLTEST_VARDIR/master-data/backup_history.log
@@ -206,15 +232,6 @@ SHOW VARIABLES LIKE 'backup_history_log'
 SHOW VARIABLES LIKE 'backup_progress_log';
 SHOW VARIABLES LIKE 'log_backup_output';
 
-TRUNCATE TABLE mysql.backup_history;
-TRUNCATE TABLE mysql.backup_progress;
-
-#
-# BUG#33364 - uncomment when purge command is implemented
-#
-# Purge the backup logs
-#PURGE BACKUP LOGS;
-
 --replace_column 1 #
 BACKUP DATABASE bup_log TO 'bup_log.bak';
 
@@ -237,6 +254,34 @@ FLUSH BACKUP LOGS;
 
 --error 0,1
 --remove_file $MYSQLTEST_VARDIR/master-data/bup_log.bak
+
+#
+# BUG#40218 Default setting incorrect
+#
+
+SET GLOBAL backup_history_log=0;
+SET GLOBAL backup_progress_log=0;
+
+--echo Should show 'OFF'
+SHOW VARIABLES LIKE 'backup%log';
+
+SET GLOBAL backup_history_log=1;
+SET GLOBAL backup_progress_log=1;
+
+--echo Should show 'ON'
+SHOW VARIABLES LIKE 'backup%log';
+
+SET GLOBAL backup_history_log=OFF;
+SET GLOBAL backup_progress_log=OFF;
+
+--echo Should show 'OFF'
+SHOW VARIABLES LIKE 'backup%log';
+
+SET GLOBAL backup_history_log=DEFAULT;
+SET GLOBAL backup_progress_log=DEFAULT;
+
+--echo After set default still should show 'ON'
+SHOW VARIABLES LIKE 'backup%log';
 
 --echo Cleanup
 DROP DATABASE bup_log;

=== added file 'mysql-test/suite/backup/t/backup_logs_purge.test'
--- a/mysql-test/suite/backup/t/backup_logs_purge.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_logs_purge.test	2008-11-17 09:57:51 +0000
@@ -0,0 +1,462 @@
+#
+# This test includes tests for ensuring the backup logs can be purged
+# of data.
+#
+
+--source include/not_embedded.inc
+--source include/have_debug_sync.inc
+--source include/have_debug.inc
+--source include/have_innodb.inc
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+
+connection con1;
+
+SET @@global.log_backup_output = 'FILE,TABLE';
+
+PURGE BACKUP LOGS;
+
+--echo 
+--echo Now starting real tests
+--echo 
+
+# Create a database and some data to work with.
+
+--disable_warnings
+DROP DATABASE IF EXISTS backup_logs;
+--enable warnings
+CREATE DATABASE backup_logs;
+
+--echo Create table and populate with data.
+
+CREATE TABLE backup_logs.t1 (a char(30)) ENGINE=MYISAM;
+CREATE TABLE backup_logs.t2 (a char(30)) ENGINE=INNODB;
+CREATE TABLE backup_logs.t3 (a char(30)) ENGINE=MEMORY;
+
+INSERT INTO backup_logs.t1 VALUES ("01 Test #1 - progress"); 
+INSERT INTO backup_logs.t1 VALUES ("02 Test #1 - progress"); 
+INSERT INTO backup_logs.t1 VALUES ("03 Test #1 - progress"); 
+INSERT INTO backup_logs.t1 VALUES ("04 Test #1 - progress"); 
+INSERT INTO backup_logs.t1 VALUES ("05 Test #1 - progress"); 
+INSERT INTO backup_logs.t1 VALUES ("06 Test #1 - progress"); 
+INSERT INTO backup_logs.t1 VALUES ("07 Test #1 - progress"); 
+
+INSERT INTO backup_logs.t2 VALUES ("01 Test #1 - progress"); 
+INSERT INTO backup_logs.t2 VALUES ("02 Test #1 - progress"); 
+INSERT INTO backup_logs.t2 VALUES ("03 Test #1 - progress"); 
+INSERT INTO backup_logs.t2 VALUES ("04 Test #1 - progress"); 
+INSERT INTO backup_logs.t2 VALUES ("05 Test #1 - progress"); 
+INSERT INTO backup_logs.t2 VALUES ("06 Test #1 - progress"); 
+
+INSERT INTO backup_logs.t3 VALUES ("01 Test #1 - progress"); 
+INSERT INTO backup_logs.t3 VALUES ("02 Test #1 - progress"); 
+INSERT INTO backup_logs.t3 VALUES ("03 Test #1 - progress"); 
+INSERT INTO backup_logs.t3 VALUES ("04 Test #1 - progress"); 
+
+#
+# Now test read of backupid with known id using debug insertion
+#
+SET SESSION debug="+d,set_backup_id";
+
+--echo Do backup of database
+BACKUP DATABASE backup_logs to 'backup1.bak';
+
+SET SESSION debug="-d";
+
+--echo Do backup of database
+BACKUP DATABASE backup_logs to 'backup2.bak';
+
+--echo Do backup of database
+BACKUP DATABASE backup_logs to 'backup3.bak';
+
+--echo Do backup of database
+BACKUP DATABASE backup_logs to 'backup4.bak';
+
+--echo Do restore of database
+RESTORE from 'backup1.bak' OVERWRITE;
+
+--echo Do restore of database
+RESTORE from 'backup2.bak' OVERWRITE;
+
+--echo Do restore of database
+RESTORE from 'backup3.bak' OVERWRITE;
+
+--echo Do restore of database
+RESTORE from 'backup4.bak' OVERWRITE;
+
+--file_exists $MYSQLTEST_VARDIR/master-data/backup1.bak
+--file_exists $MYSQLTEST_VARDIR/master-data/backup2.bak
+--file_exists $MYSQLTEST_VARDIR/master-data/backup3.bak
+--file_exists $MYSQLTEST_VARDIR/master-data/backup4.bak
+
+--echo Display results from backup logs
+SELECT backup_id FROM mysql.backup_history;
+SELECT DISTINCT backup_id FROM mysql.backup_progress;
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+--echo Purge all backup log data prior to id = 502.
+PURGE BACKUP LOGS TO 502;
+
+--echo Display results from backup logs
+SELECT backup_id FROM mysql.backup_history;
+SELECT DISTINCT backup_id FROM mysql.backup_progress;
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+--echo Purge all backup log data.
+PURGE BACKUP LOGS;
+
+--echo Display results from backup logs
+SELECT backup_id FROM mysql.backup_history;
+SELECT DISTINCT backup_id FROM mysql.backup_progress;
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+--echo Cleanup the logs and images for later testing.
+PURGE BACKUP LOGS;
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/backup1.bak
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/backup2.bak
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/backup3.bak
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/backup4.bak
+
+SET @@time_zone = '+00:00';
+
+SET SESSION debug="+d,set_backup_id";
+
+--echo Do backup of database
+BACKUP DATABASE backup_logs to 'backup1.bak';
+
+SET SESSION debug="-d";
+
+--echo Do backup of database
+BACKUP DATABASE backup_logs to 'backup2.bak';
+
+--echo Do backup of database
+BACKUP DATABASE backup_logs to 'backup3.bak';
+
+SET SESSION debug="+d,set_log_time";
+
+--echo Do backup of database
+BACKUP DATABASE backup_logs to 'backup4.bak';
+
+SET SESSION debug="-d";
+
+--echo Do restore of database
+RESTORE from 'backup1.bak' OVERWRITE;
+
+--echo Do restore of database
+RESTORE from 'backup2.bak' OVERWRITE;
+
+--echo Do restore of database
+RESTORE from 'backup3.bak' OVERWRITE;
+
+SET SESSION debug="+d,set_log_time";
+
+--echo Do restore of database
+RESTORE from 'backup4.bak' OVERWRITE;
+
+SET SESSION debug="-d";
+
+--file_exists $MYSQLTEST_VARDIR/master-data/backup1.bak
+--file_exists $MYSQLTEST_VARDIR/master-data/backup2.bak
+--file_exists $MYSQLTEST_VARDIR/master-data/backup3.bak
+--file_exists $MYSQLTEST_VARDIR/master-data/backup4.bak
+
+--echo Display the results.
+SELECT backup_id FROM mysql.backup_history;
+SELECT DISTINCT backup_id FROM mysql.backup_progress;
+
+#
+# We need to sleep to allow time to pass in order to ensure the time
+# compare method in log.cc has two different times to compare.
+#
+real_sleep 3;
+
+SET @now_time= now();
+
+PURGE BACKUP LOGS BEFORE @now_time; 
+
+SELECT backup_id FROM mysql.backup_history;
+SELECT DISTINCT backup_id FROM mysql.backup_progress;
+
+SET @@time_zone = @@global.time_zone;
+
+PURGE BACKUP LOGS;
+
+#
+# Test purge of logs for locations other than backupdir.
+#
+--echo Perform backup
+SET SESSION debug="+d,set_backup_id";
+
+BACKUP DATABASE backup_logs TO '../bup_logs_dir.bak';
+
+SET SESSION debug="-d";
+
+--echo Ensure backup image file went to the correct location
+--file_exists $MYSQLTEST_VARDIR/bup_logs_dir.bak
+
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+PURGE BACKUP LOGS TO 501;
+
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+#
+# Test error conditions.
+#
+
+--error ER_BACKUP_PURGE_DATETIME
+PURGE BACKUP LOGS BEFORE 123123;
+
+SET @@global.log_backup_output = 'FILE';
+
+--error ER_BACKUP_LOG_OUTPUT
+PURGE BACKUP LOGS TO 99999999;
+
+--error ER_BACKUP_LOG_OUTPUT
+PURGE BACKUP LOGS BEFORE @now_time;
+
+SET @@global.log_backup_output = 'TABLE';
+
+#
+# Now test what happens when PURGE is run at the same
+# time as a backup or restore is run.
+#
+
+--echo Test backup and purge concurrent execution.
+
+PURGE BACKUP LOGS;
+
+--echo Get rid of any lingering image files.
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/backup1.bak
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/backup2.bak
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/backup3.bak
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/backup4.bak
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/bup_logs_dir.bak
+
+SET DEBUG_SYNC= 'RESET';
+
+connection con1;
+
+--echo con2: Do some backups to add entries in logs.
+--replace_column 1 #
+BACKUP DATABASE backup_logs to 'backup1.bak';
+--replace_column 1 #
+BACKUP DATABASE backup_logs to 'backup2.bak';
+--replace_column 1 #
+BACKUP DATABASE backup_logs to 'backup3.bak';
+--replace_column 1 #
+BACKUP DATABASE backup_logs to 'backup4.bak';
+
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+connection con2;
+
+SET SESSION debug="+d,set_backup_id";
+
+#
+# Stop backup after it has written rows to the logs but before
+# it writes the history log and last complete log entry.
+#
+--echo con2: Activate sync points for the backup statement.
+SET DEBUG_SYNC= 'before_backup_done SIGNAL ready WAIT_FOR proceed';
+SEND BACKUP DATABASE backup_logs to 'backup5.bak';
+
+connection con1;
+
+--echo con1: Wait for the backup to be ready.
+SET DEBUG_SYNC= 'now WAIT_FOR ready';
+
+PURGE BACKUP LOGS;
+
+SET DEBUG_SYNC= 'now SIGNAL proceed';
+
+connection con2;
+--replace_column 1 #
+reap;
+
+SET SESSION debug="-d";
+
+connection con1;
+
+--echo There should be one row in this table: the backup id from last
+--echo backup (500).
+SELECT count(*) FROM mysql.backup_history;
+SELECT backup_id, command FROM mysql.backup_history;
+
+--echo There should be one row in this table: the backup id from last
+--echo backup (500). We should only see the complete progress 
+--echo statement because all others were deleted while backup was
+--echo in progress.
+SELECT count(*) FROM mysql.backup_progress;
+--replace_column 3 # 4 #
+--query_vertical SELECT * FROM mysql.backup_progress
+
+--echo Now do the same test for restore.
+
+--replace_column 1 #
+RESTORE FROM 'backup1.bak' OVERWRITE;
+--replace_column 1 #
+RESTORE FROM 'backup2.bak' OVERWRITE;
+--replace_column 1 #
+RESTORE FROM 'backup3.bak' OVERWRITE;
+--replace_column 1 #
+RESTORE FROM 'backup4.bak' OVERWRITE;
+
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+connection con2;
+
+#
+# Stop restore after it has written rows to the logs but before
+# it writes the history log and last complete log entry.
+#
+--echo con2: Activate sync points for the backup statement.
+SET DEBUG_SYNC= 'before_restore_done SIGNAL ready WAIT_FOR proceed';
+SEND RESTORE FROM 'backup5.bak' OVERWRITE;
+
+connection con1;
+
+--echo con1: Wait for the backup to be ready.
+SET DEBUG_SYNC= 'now WAIT_FOR ready';
+
+PURGE BACKUP LOGS;
+
+SET DEBUG_SYNC= 'now SIGNAL proceed';
+
+connection con2;
+--replace_column 1 #
+reap;
+
+connection con1;
+
+--echo There should be one row in this table: the backup id from last
+--echo restore (505).
+SELECT count(*) FROM mysql.backup_history;
+SELECT backup_id, command FROM mysql.backup_history;
+
+--echo There should be one row in this table: the backup id from last
+--echo restore (505). We should only see the complete progress 
+--echo statement because all others were deleted while restore was
+--echo in progress.
+SELECT count(*) FROM mysql.backup_progress;
+--replace_column 3 # 4 #
+--query_vertical SELECT * FROM mysql.backup_progress
+
+#
+# Test removal of entries that do not meet criteria and
+# removal of all entries.
+#
+
+--remove_file $MYSQLTEST_VARDIR/master-data/backup1.bak
+--remove_file $MYSQLTEST_VARDIR/master-data/backup2.bak
+--remove_file $MYSQLTEST_VARDIR/master-data/backup3.bak
+--remove_file $MYSQLTEST_VARDIR/master-data/backup4.bak
+--remove_file $MYSQLTEST_VARDIR/master-data/backup5.bak
+
+--echo First, run some backups.
+
+--replace_column 1 #
+BACKUP DATABASE backup_logs TO 'backup1.bak';
+--replace_column 1 #
+BACKUP DATABASE backup_logs TO 'backup2.bak';
+--replace_column 1 #
+BACKUP DATABASE backup_logs TO 'backup3.bak';
+--replace_column 1 #
+BACKUP DATABASE backup_logs TO 'backup4.bak';
+--replace_column 1 #
+BACKUP DATABASE backup_logs TO 'backup5.bak';
+
+--echo Test purges that do not meet criteria.
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+PURGE BACKUP LOGS BEFORE '1988-10-12 12:00:00';
+
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+PURGE BACKUP LOGS TO 0;
+
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+--echo Test empty logs (delete all entries).
+
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+PURGE BACKUP LOGS TO 999999999;
+
+--echo Check to be sure backup logs are empty (count(*) = 0).
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+--remove_file $MYSQLTEST_VARDIR/master-data/backup1.bak
+--remove_file $MYSQLTEST_VARDIR/master-data/backup2.bak
+--remove_file $MYSQLTEST_VARDIR/master-data/backup3.bak
+--remove_file $MYSQLTEST_VARDIR/master-data/backup4.bak
+--remove_file $MYSQLTEST_VARDIR/master-data/backup5.bak
+
+--echo Run some more backups to generate more rows.
+
+--replace_column 1 #
+BACKUP DATABASE backup_logs TO 'backup1.bak';
+--replace_column 1 #
+BACKUP DATABASE backup_logs TO 'backup2.bak';
+--replace_column 1 #
+BACKUP DATABASE backup_logs TO 'backup3.bak';
+--replace_column 1 #
+BACKUP DATABASE backup_logs TO 'backup4.bak';
+--replace_column 1 #
+BACKUP DATABASE backup_logs TO 'backup5.bak';
+
+--echo Test purges that do not meet criteria.
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+PURGE BACKUP LOGS BEFORE '2024-10-12 12:00:00';
+
+--echo Test empty logs (delete all entries).
+
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+
+#
+# Cleanup.
+#
+
+SET DEBUG_SYNC= 'RESET';
+
+DROP DATABASE backup_logs;
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/backup1.bak
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/backup2.bak
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/backup3.bak
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/backup4.bak
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/backup5.bak
+
+PURGE BACKUP LOGS;
+
+

=== modified file 'mysql-test/suite/backup/t/backup_no_be.test'
--- a/mysql-test/suite/backup/t/backup_no_be.test	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_no_be.test	2008-11-17 09:57:51 +0000
@@ -33,7 +33,7 @@ INSERT INTO t1 VALUES (1),(2),(3);
 # First check the normal behaviour when server is not modified.
 
 # make sure that injected code is disabled
-SET SESSION debug="d,";
+SET SESSION debug="-d,";
 SELECT @@debug;
 
 # BACKUP should succeed without a warning.
@@ -56,7 +56,7 @@ SELECT drivers FROM mysql.backup_history
 # Now see what happens when injected code is activated and MyISAM uses the dummy
 # factory function.
 
-SET SESSION debug="d,backup_test_dummy_be_factory";
+SET SESSION debug="+d,backup_test_dummy_be_factory";
 SELECT @@debug;
 
 # The following BACKUP command should generate a warning but otherwise
@@ -84,12 +84,12 @@ SELECT drivers FROM mysql.backup_history
 # check that we can restore from the created image.
 
 --replace_column 1 #
-RESTORE FROM 'db1.bak';
+RESTORE FROM 'db1.bak' OVERWRITE;
 SHOW TABLES IN db1;
 
 
 # Clean up.
 
 DROP DATABASE db1;
-SET GLOBAL debug="d,";
+SET GLOBAL debug="-d,";
 --remove_file $MYSQLTEST_VARDIR/master-data/db1.bak

=== modified file 'mysql-test/suite/backup/t/backup_no_data.test'
--- a/mysql-test/suite/backup/t/backup_no_data.test	2008-10-09 09:55:08 +0000
+++ b/mysql-test/suite/backup/t/backup_no_data.test	2008-11-20 14:07:23 +0000
@@ -26,7 +26,7 @@ DROP DATABASE other_db;
 SHOW DATABASES;
 
 --replace_column 1 #
-RESTORE FROM 'all.bak';
+RESTORE FROM 'all.bak' OVERWRITE;
 
 SHOW DATABASES;
 
@@ -40,7 +40,7 @@ SHOW DATABASES;
 SHOW TABLES IN empty_db;
 
 --replace_column 1 #
-RESTORE FROM 'all.bak';
+RESTORE FROM 'all.bak' OVERWRITE;
 
 SHOW DATABASES;
 SHOW TABLES IN empty_db;
@@ -64,7 +64,7 @@ BACKUP DATABASE empty_db TO 'empty_db.ba
 SHOW DATABASES;
 
 --replace_column 1 #
-RESTORE FROM 'empty_db.bak';
+RESTORE FROM 'empty_db.bak' OVERWRITE;
 
 USE empty_db;
 

=== added file 'mysql-test/suite/backup/t/backup_nodata_driver-master.opt'
--- a/mysql-test/suite/backup/t/backup_nodata_driver-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_nodata_driver-master.opt	2008-11-21 15:02:34 +0000
@@ -0,0 +1 @@
+$EXAMPLE_PLUGIN_OPT

=== modified file 'mysql-test/suite/backup/t/backup_nodata_driver.test'
--- a/mysql-test/suite/backup/t/backup_nodata_driver.test	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_nodata_driver.test	2008-11-21 15:02:34 +0000
@@ -1,5 +1,9 @@
 #
 # This test tests the backup using no data engines.
+# These are engines which tables don't contain data.
+# This is obvious for BLACKHOLE and EXAMPLE.
+# Other engines behave like placeholders for tables of other
+# engines and don't have data themselves. Examples are MERGE and FEDERATED.
 # It was made a separate test due to the possibility that some
 # of the engines used may not be available on all platforms or
 # builds.
@@ -10,18 +14,26 @@
 #
 --source include/not_embedded.inc
 --source include/have_federated_db.inc
---source include/have_exampledb.inc
+# MERGE is always available --source include/have_merge.inc
 --source include/have_blackhole.inc
+#
+# Example engine must be loaded as plugin.
+# Currently this does not work on Windows yet.
+#
+--source include/not_windows.inc
+--source include/have_example_plugin.inc
+INSTALL PLUGIN example SONAME 'ha_example.so';
+--source include/have_exampledb.inc
 
 --disable_warnings
 DROP DATABASE IF EXISTS bup_nodata;
 DROP DATABASE IF EXISTS bup_data;
 --enable_warnings
 
-# Create data
---echo Creating tables
-CREATE DATABASE bup_nodata;
-
+--echo #
+--echo # Create a database with tables that can work as
+--echo # base tables for MERGE and FEDERATED.
+--echo #
 CREATE DATABASE bup_data;
 
 CREATE TABLE bup_data.myisam1 (a int, b char(30)) ENGINE=MYISAM;
@@ -39,6 +51,11 @@ CREATE TABLE bup_data.f1 (
     )
   DEFAULT CHARSET=latin1;
 
+--echo #
+--echo # Create a database with tables from no-data engines.
+--echo #
+CREATE DATABASE bup_nodata;
+
 CREATE TABLE bup_nodata.merge1 (a int, b char(30))
   ENGINE=MERGE UNION=(bup_data.myisam1, bup_data.myisam2, bup_data.myisam3);
 
@@ -60,8 +77,9 @@ CREATE TABLE bup_nodata.e1 (
   Vapor_period smallint(4) unsigned DEFAULT '0' NOT NULL
 ) ENGINE=example;
 
-# Insert some data (for merge and federated to ensure proper working tables)
---echo Inserting data
+--echo #
+--echo # Insert some data.
+--echo #
 INSERT INTO bup_data.myisam1 VALUES (11, 'table 1');
 INSERT INTO bup_data.myisam1 VALUES (12, 'table 1');
 INSERT INTO bup_data.myisam1 VALUES (13, 'table 1');
@@ -78,89 +96,152 @@ INSERT INTO bup_data.f1 (id, `group`) VA
 INSERT INTO bup_data.f1 (id, `batch`) VALUES (4, 23);
 INSERT INTO bup_data.f1 (id, `qty`) VALUES (5, 1);
 
-# Show the data
---echo show data
+--echo #
+--echo # Show the data.
+--echo #
 SHOW FULL TABLES FROM bup_data;
 SHOW FULL TABLES FROM bup_nodata;
-
 SELECT * FROM bup_nodata.merge1;
 SELECT * FROM bup_nodata.f1;
 SELECT * FROM bup_nodata.b1;
 SELECT * FROM bup_nodata.e1;
 
-# Do the backup of the bup_data DB.
+--echo #
+--echo # Backup the bup_data DB, which tables contain data.
+--echo #
 --replace_column 1 #
 BACKUP DATABASE bup_data TO 'bup_data.bak';
 
-# Do the backup of the bup_nodata DB.
+--echo #
+--echo # Backup the bup_nodata DB, which tables do not contain data.
+--echo #
 --replace_column 1 #
 BACKUP DATABASE bup_nodata TO 'bup_nodata.bak';
 
-# Show the data
---echo show data
+--echo #
+--echo # Show the data again. Backup did not modify them.
+--echo #
 SHOW FULL TABLES FROM bup_data;
 SHOW FULL TABLES FROM bup_nodata;
-
 SELECT * FROM bup_nodata.merge1;
 SELECT * FROM bup_nodata.f1;
 SELECT * FROM bup_nodata.b1;
 SELECT * FROM bup_nodata.e1;
 
-# Now drop the data database and show what is left
-
+--echo #
+--echo # Now drop the bup_data database.
+--echo #
 DROP DATABASE bup_data;
 
-# Show the data
---echo show data
+--echo #
+--echo # Show that the data have gone.
+--echo # The MERGE and FEDERATED tables have errors since
+--echo # their base tables have been dropped with bup_data.
+--echo #
 SHOW FULL TABLES FROM bup_nodata;
-
-# The merge and federated tables should have errors since data is missing.
---error ER_NO_SUCH_TABLE
+--error ER_WRONG_MRG_TABLE
 SELECT * FROM bup_nodata.merge1;
 --error ER_CONNECT_TO_FOREIGN_DATA_SOURCE,ER_QUERY_ON_FOREIGN_DATA_SOURCE
 SELECT * FROM bup_nodata.f1;
 SELECT * FROM bup_nodata.b1;
 SELECT * FROM bup_nodata.e1;
 
+--echo #
+--echo # Now drop the bup_nodata database too.
+--echo #
 DROP DATABASE bup_nodata;
 
-# Now restore the nodata database and see if it is the same as above.
---echo Restoring nodata database.
+--echo #
+--echo # Now try to restore the bup_nodata database. This fails because
+--echo # restore opens the tables for filling them with data, even when
+--echo # they were empty on backup. 'bup_nodata.bak' does not contain
+--echo # the base tables for the MERGE and FEDERATED tables.
+--echo # NOTE: Since restore fails after restoring the meta data,
+--echo # after creating the tables that is, we have the same
+--echo # situation as before. The tables exist, but the base
+--echo # tables for MERGE and FEDERATED do not exist.
+--echo #
 --replace_column 1 #
-RESTORE FROM 'bup_nodata.bak';
+--error ER_WRONG_MRG_TABLE,ER_CONNECT_TO_FOREIGN_DATA_SOURCE,ER_QUERY_ON_FOREIGN_DATA_SOURCE
+RESTORE FROM 'bup_nodata.bak' OVERWRITE;
 
-# Show the data
---echo show data
+--echo #
+--echo # Show what we have.
+--echo # NOTE: If restore would work as all or nothing,
+--echo # all of the SHOW and SELECT statements in this section would fail.
+--echo #
 SHOW FULL TABLES FROM bup_nodata;
-
-# The merge and federated tables should have errors since data is missing.
---error ER_NO_SUCH_TABLE
+--error ER_WRONG_MRG_TABLE
 SELECT * FROM bup_nodata.merge1;
 --error ER_CONNECT_TO_FOREIGN_DATA_SOURCE,ER_QUERY_ON_FOREIGN_DATA_SOURCE
 SELECT * FROM bup_nodata.f1;
 SELECT * FROM bup_nodata.b1;
 SELECT * FROM bup_nodata.e1;
 
-# Now restore the data database and see that all is well.
---echo Restoring data database.
+--echo #
+--echo # Now restore the bup_data database as well.
+--echo #
 --replace_column 1 #
 RESTORE FROM 'bup_data.bak';
 
-# Show the data
---echo show data
+--echo #
+--echo # Show that everything is well.
+--echo # NOTE: If restore would work as all or nothing,
+--echo # the bup_nodata tables would not exist here.
+--echo #
 SHOW FULL TABLES FROM bup_data;
 SHOW FULL TABLES FROM bup_nodata;
+SELECT * FROM bup_nodata.merge1;
+SELECT * FROM bup_nodata.f1;
+SELECT * FROM bup_nodata.b1;
+SELECT * FROM bup_nodata.e1;
+
+--echo #
+--echo # Now restore the bup_nodata database and see if it is the same
+--echo # as above. Note that this step would not be required here
+--echo # because all bup_nodata tables have no data and were created
+--echo # by the failed restore. Anyway, the correct approach is to do a
+--echo # succeeding restore before assuming that everything exists again.
+--echo #
+--replace_column 1 #
+RESTORE FROM 'bup_nodata.bak' OVERWRITE;
 
+--echo #
+--echo # Show that everything is well.
+--echo #
+SHOW FULL TABLES FROM bup_nodata;
 SELECT * FROM bup_nodata.merge1;
 SELECT * FROM bup_nodata.f1;
 SELECT * FROM bup_nodata.b1;
 SELECT * FROM bup_nodata.e1;
 
+--echo #
+--echo # Now drop the bup_data database with the base tables again.
+--echo #
 DROP DATABASE bup_data;
+
+--echo #
+--echo # Show that the data have gone.
+--echo # The MERGE and FEDERATED tables have errors since
+--echo # their base tables have been dropped with bup_data.
+--echo #
+SHOW FULL TABLES FROM bup_nodata;
+--error ER_WRONG_MRG_TABLE
+SELECT * FROM bup_nodata.merge1;
+--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE,ER_QUERY_ON_FOREIGN_DATA_SOURCE
+SELECT * FROM bup_nodata.f1;
+SELECT * FROM bup_nodata.b1;
+SELECT * FROM bup_nodata.e1;
+
+--echo #
+--echo # Cleanup.
+--echo #
 DROP DATABASE bup_nodata;
 
 --error 0,1
 --remove_file $MYSQLTEST_VARDIR/master-data/bup_data.bak
 --error 0,1
 --remove_file $MYSQLTEST_VARDIR/master-data/bup_nodata.bak
+
+UNINSTALL PLUGIN example;
 

=== modified file 'mysql-test/suite/backup/t/backup_security.test'
--- a/mysql-test/suite/backup/t/backup_security.test	2008-10-24 08:25:48 +0000
+++ b/mysql-test/suite/backup/t/backup_security.test	2008-11-17 09:57:51 +0000
@@ -72,7 +72,7 @@ BACKUP DATABASE backup_test to 'bup_with
 
 --echo no_rights: Attempting restore. Should succeed
 --replace_column 1 #
-RESTORE FROM 'bup_with_rights.bak';
+RESTORE FROM 'bup_with_rights.bak' OVERWRITE;
 
 SELECT * FROM backup_test.t1;
 
@@ -82,7 +82,7 @@ disconnect with_rights;
 connection default;
 
 --replace_column 1 #
-RESTORE FROM 'backup_test_orig.bak';
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
 
 SELECT * FROM backup_test.t1;
 

=== modified file 'mysql-test/suite/backup/t/backup_snapshot.test'
--- a/mysql-test/suite/backup/t/backup_snapshot.test	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_snapshot.test	2008-11-17 09:57:51 +0000
@@ -116,7 +116,7 @@ DROP TABLE bup_snapshot.t1;
 
 --echo con1: Restoring the database
 --replace_column 1 #
-RESTORE FROM "bup_snapshot.bak";
+RESTORE FROM "bup_snapshot.bak" OVERWRITE;
 
 --echo con1: Showing the data (no new data should be here).
 SELECT * FROM bup_snapshot.t1 WHERE word LIKE '-%';
@@ -175,7 +175,7 @@ DROP TABLE bup_snapshot.t1;
 
 --echo con1: Restoring the database
 --replace_column 1 #
-RESTORE FROM "bup_snapshot.bak";
+RESTORE FROM "bup_snapshot.bak" OVERWRITE;
 
 --echo con1: Showing the data (no new data should be here).
 SELECT * FROM bup_snapshot.t1 WHERE word LIKE '-%';

=== modified file 'mysql-test/suite/backup/t/backup_timeout.test'
--- a/mysql-test/suite/backup/t/backup_timeout.test	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_timeout.test	2008-11-19 22:01:28 +0000
@@ -159,4 +159,6 @@ SHOW VARIABLES LIKE 'backup_wait%';
 
 DROP DATABASE bup_ddl_blocker;
 
+SET DEBUG_SYNC= 'reset';
+
 --remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker.bak

=== removed file 'mysql-test/suite/backup/t/backup_view_on_view.test'
--- a/mysql-test/suite/backup/t/backup_view_on_view.test	2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_view_on_view.test	1970-01-01 00:00:00 +0000
@@ -1,32 +0,0 @@
-# Test case for bug#34758
-
---source include/not_embedded.inc
---source include/have_debug.inc
---source include/have_innodb.inc
-
-# Setup the server to use the backup breakpoints
-SET GLOBAL debug="d,backup:d,backup_data";
-
---disable_warnings
-DROP DATABASE IF EXISTS db1;
---enable_warnings
-
-CREATE DATABASE db1;
-
-CREATE TABLE db1.t1(a int) ENGINE=INNODB;
-CREATE VIEW db1.v1 AS SELECT * FROM db1.t1;
-CREATE VIEW db1.v2 AS SELECT * FROM db1.v1;
-
-INSERT INTO db1.t1 VALUES (1),(2),(3),(5),(7),(11);
-
-replace_column 1 #;
-BACKUP DATABASE db1 TO 'test.bak';
-replace_column 1 #;
-RESTORE FROM 'test.bak';
-
-SELECT * FROM db1.v2;
-SELECT * FROM db1.v1;
-SELECT * FROM db1.t1;
-
-DROP DATABASE db1;
-

=== added file 'mysql-test/suite/backup/t/backup_vp_nontx.test'
--- a/mysql-test/suite/backup/t/backup_vp_nontx.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_vp_nontx.test	2008-11-20 09:49:34 +0000
@@ -0,0 +1,256 @@
+#
+# This test is one of two validity point tests. See:
+#    backup_vp_tx.test
+#
+# The goal of the test should be to ensure the following assumptions
+# for the behavior of validity point (VP) hold. Validity point is
+# implemented using commit blocker (CB).
+#
+# Note: in this file, "DML" refers to DML operations executed in
+#       non-transactional storage engines.
+#
+# a) DMLs that are executed before VP are in the backup image
+#
+# b) setting the validity point should not be done while DMLs are
+#    being processed in any table involved in the backup. An active
+#    DML therefore blocks backup from setting commit blocker. The DML
+#    has to complete before backup can set CB (and ultimately set the
+#    VP), and will therefore be in the backup image
+#
+# c) setting the validity point should not be done while DMLs are
+#    being processed in any table involved in the backup. A DML
+#    operation requested when backup is ready to set VP is therefore
+#    blocked by CB. The DML has to wait for CB to be released before
+#    it can continue, and will therefore not be in the backup image
+#
+# d) DMLs executed after VP are not in the backup image
+#
+#
+
+--source include/have_debug_sync.inc
+--source include/not_embedded.inc
+
+--disable_warnings
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE IF EXISTS bup_vp;
+
+let $bdir=`SELECT @@backupdir`;
+
+--error 0,1
+remove_file $bdir/bup_vp.bak;
+--enable_warnings
+
+
+CREATE DATABASE bup_vp;
+
+#
+# Connections used in this test
+#
+# con_bup  - used to create data, load data, and run the backup 
+# con_ntx1 - used for non-transactional execution
+# con_ntx2 - used for non-transactional execution
+# con_sync - used to make sync point work flow easier to read
+#
+
+connect (con_bup,localhost,root,,);
+connect (con_ntx1,localhost,root,,);
+connect (con_ntx2,localhost,root,,);
+connect (con_sync,localhost,root,,);
+
+connection con_bup;
+
+--echo 
+--echo Starting Test
+--echo 
+
+#
+# Sequence diagram (not UML), only relevant parts shown
+#
+#      bup     tx1      tx2
+#       |       |        | 
+#       a)      |        | 
+#    (setup)    |        | 
+#       |       b)       | 
+#       |    INSERT      | 
+#     BACKUP  <...>      | 
+#     SET CB  <...>      | 
+#     <###>   <...>      | 
+#     <...>     |        c)
+#       |       |     INSERT
+#    SET VP     |      <###>
+#   RELEASE CB  |      <###>
+#       |       d)     <...>
+#       |    INSERT      | 
+#    BUP DONE   |        | 
+#   (results)   |        | 
+#
+# Note: Ongoing operations are indicated with <...>
+#       Blocked operations are indicated with <###>
+#
+
+# Create transaction tables and load them with data.
+--echo con_bup: Creating tables
+CREATE TABLE bup_vp.t1 (col_a CHAR(40)) ENGINE=MEMORY;
+
+--echo con_bup: Loading data
+--echo con_bup: Scenario a) - commited before backup
+INSERT INTO bup_vp.t1 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("05 Some data to test");
+
+--echo 
+--echo con_bup: Show the data before we start backup
+SELECT * FROM bup_vp.t1;
+
+### CON 1 ###
+  --echo 
+  connection con_ntx1;
+
+  --echo Scenario (b): Insert in progress blocks CB and is included in backup
+  --echo con_ntx1: Start insert and stop it in the middle of processing
+
+  --echo con_ntx1: Make insert stop in the middle of execution
+  # Will continue once backup has been blocked from setting CB
+  SET DEBUG_SYNC= 'after_insert_locked_tables SIGNAL insert_started
+                   WAIT_FOR complete_insert';
+  send INSERT INTO bup_vp.t1 VALUES ("ntx1: 06 Some data to test");
+
+
+### CON BUP ###
+--echo 
+connection con_bup;
+
+# Backup will be blocked from setting CB by the ongoing insert in
+# con_ntx1. Backup will signal con_ntx1 that it has been blocked. The
+# insert will then finish, making backup able to set CB. When CB has
+# been set, ntx2 will be signaled to try to insert. ntx2 insert will
+# be blocked by the CB and send a signal that it has been blocked. CB
+# is then released, but backup is stopped immediately after releasing
+# CB. ntx2 will now be able to complete the insert, and ntx1 will
+# issue and complete another insert. Finally, backup is allowed to
+# complete.
+
+--echo con_bup: Activate synchronization points for BACKUP.
+# Signal when backup is blocked by ongoing insert in con_ntx1
+SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL sync_complete_insert';
+
+# ntx1 insert is completed, so backup can set CB. Just before reaching
+# VP, signal ntx2 should try to insert. Wait until ntx2 signals it has
+# been blocked
+SET DEBUG_SYNC= 'before_backup_data_lock SIGNAL try_insert
+                 WAIT_FOR insert_blocked';
+
+# ntx2 insert has been blocked. Create VP and release CB, and then wait
+# while ntx2 and ntx1 inserts.
+SET DEBUG_SYNC= 'after_backup_binlog SIGNAL commit_unblocked
+                 WAIT_FOR finish_bup';
+
+--echo con_bup: Backing up database -- will block with lock
+send BACKUP DATABASE bup_vp TO "bup_vp.bak";
+
+### CON SYNC ###
+--echo 
+connection con_sync;
+SET DEBUG_SYNC= 'now WAIT_FOR sync_complete_insert';
+--echo Backup has been blocked by ongoing insert
+
+# cannot test with select that insert has not completed ntx1 has X-lock
+SET DEBUG_SYNC= 'now SIGNAL complete_insert';
+
+### CON 1 ###
+  --echo 
+  connection con_ntx1;
+  --echo con_ntx1: Reap insert
+  reap;
+
+  --echo Check that record has been inserted; Should be 1 record
+  SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx1%';
+  --echo 
+
+###########
+## Below this line happens after BACKUP has taken CB
+###########
+
+### CON 2 ###
+    connection con_ntx2;
+
+    --echo con_ntx2: Wait until backup has set CB, then try to insert
+    # Wait for backup to set CB
+    SET DEBUG_SYNC= 'now WAIT_FOR try_insert';
+    # Signal to backup that the insert is blocked
+    SET DEBUG_SYNC= 'wait_if_global_read_lock SIGNAL sync_insert_blocked';
+    send INSERT INTO bup_vp.t1 VALUES ("ntx2: Should NOT be in backup");
+
+    # INSERT is blocked until CB has been released
+
+### CON SYNC ###
+--echo 
+connection con_sync;
+SET DEBUG_SYNC= 'now WAIT_FOR sync_insert_blocked';
+
+--echo Insert in ntx2 is blocked and should not be in t1; Should be 0 records
+SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx2%';
+--echo 
+
+SET DEBUG_SYNC= 'now SIGNAL insert_blocked';
+
+
+### CON 1 ###
+  --echo 
+  connection con_ntx1;
+
+  --echo con_ntx1: Backup has now released CB. Perform insert
+  # Double-check that backup has reached sync point after CB release
+  SET DEBUG_SYNC= 'now WAIT_FOR commit_unblocked';
+  INSERT INTO bup_vp.t1 VALUES ("ntx1: Should NOT be in backup");
+  SET DEBUG_SYNC= 'now SIGNAL finish_bup';
+
+
+### CON BUP ###
+--echo 
+connection con_bup;
+--echo con_ntx1: Reap backup
+--replace_column 1 #
+reap;
+
+
+###########
+## Verify results
+###########
+
+# Do selects to show that all changes got applied.
+--echo 
+--echo con_bup: Showing data after updates and backup
+SELECT * FROM bup_vp.t1;
+
+--echo con_bup: Dropping the database
+DROP TABLE bup_vp.t1;
+DROP DATABASE bup_vp;
+
+--echo con_bup: Restoring the database
+--replace_column 1 #
+RESTORE FROM "bup_vp.bak";
+
+--echo 
+--echo con_bup: Showing the data after restore
+SELECT * FROM bup_vp.t1;
+
+--echo
+--echo Verifying results:
+--echo
+
+--echo T1 should have changes from con_ntx1; Should be 1 record
+SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx1%';
+--echo 
+
+--echo T1 should not have the changes from con_ntx2; Should be 0 records
+SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx2%';
+--echo 
+
+--echo con_bup: Cleanup
+DROP DATABASE bup_vp;
+
+remove_file $bdir/bup_vp.bak;
+SET DEBUG_SYNC= 'RESET';

=== added file 'mysql-test/suite/backup/t/backup_vp_tx.test'
--- a/mysql-test/suite/backup/t/backup_vp_tx.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_vp_tx.test	2008-11-20 09:49:34 +0000
@@ -0,0 +1,329 @@
+#
+# This test is one of two validity point tests. See:
+#    backup_vp_nontx.test
+#
+# The goal of the test should be to ensure the following assumptions
+# for the behavior of validity point (VP) hold. Validity point is
+# implemented using commit blocker (CB).
+#
+# a) transactions that commit before VP are in the backup image
+#
+# b) setting the validity point should not be done while commits are
+#    being processed in any table involved in the backup. Transactions
+#    with ongoing commits therefore block backup from setting commit
+#    blocker. The commit has to complete before backup can set CB (and
+#    ultimately set the VP), and will therefore be in the backup image
+#
+# c) setting the validity point should not be done while commits are
+#    being processed in any table involved in the backup. Transactions
+#    that try to commit when backup is ready to set VP are therefore
+#    blocked by CB. The commit has to wait for CB to be released
+#    before it can continue, and will therefore not be in the backup
+#    image
+#
+# d) transactions that commit after VP are not in the backup image
+#
+# Note: the transactions have to modify data.
+#
+#
+#
+
+--source include/have_innodb.inc
+--source include/have_debug_sync.inc
+--source include/not_embedded.inc
+
+--disable_warnings
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE IF EXISTS bup_vp;
+
+let $bdir=`SELECT @@backupdir`;
+
+--error 0,1
+remove_file $bdir/bup_vp.bak;
+--enable_warnings
+
+CREATE DATABASE bup_vp;
+
+#
+# Connections used in this test
+#
+# con_bup  - used to create data, load data, and run the backup 
+# con_tx1  - used for transactional execution
+# con_tx2  - used for transactional execution
+# con_tx3  - used for transactional execution
+# con_sync - used to make sync point work flow easier to read
+#
+
+connect (con_bup,localhost,root,,);
+connect (con_tx1,localhost,root,,);
+connect (con_tx2,localhost,root,,);
+connect (con_tx3,localhost,root,,);
+connect (con_sync,localhost,root,,);
+
+connection con_bup;
+
+--echo 
+--echo Starting Test
+--echo 
+
+#
+# Sequence diagram (not UML), only relevant parts shown
+#
+#      bup     tx1      tx2      tx3
+#       |       |        |        |
+#       a)      |        |        |
+#    (setup)    |        |        |
+#     COMMIT    |        |        d)
+#       |       |        |      BEGIN
+#       |       b)       |    INSERT t3
+#       |     BEGIN      |        |
+#       |   INSERT t1    |        |
+#       |     COMMIT     c)       |
+#       |     <...>    BEGIN      |
+#       |     <...>  INSERT t2    |
+#       |     <...>      |        |   
+#     BACKUP  <...>      |        |
+#     SET CB  <...>      |        |   
+#     <###>   <...>      |        |  
+#     <...>     |        |        |  
+#       |       |     COMMIT      |  
+#    SET VP     |      <###>      |   
+#   RELEASE CB  |      <###>      |  
+#       |       |      <...>    COMMIT
+#       |       |        |        |  
+#    BUP DONE   |        |        |  
+#   (results)   |        |        |     
+#
+# Note: Ongoing operations are indicated with <...>
+#       Blocked operations are indicated with <###>
+#
+
+# Create transaction tables and load them with data.
+--echo con_bup: Creating tables
+CREATE TABLE bup_vp.t1 (col_a CHAR(40)) ENGINE=INNODB;
+CREATE TABLE bup_vp.t2 (col_a CHAR(40)) ENGINE=INNODB;
+CREATE TABLE bup_vp.t3 (col_a CHAR(40)) ENGINE=INNODB;
+
+--echo 
+--echo con_bup: Loading data
+--echo con_bup: Scenario a) - commited before backup
+INSERT INTO bup_vp.t1 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("05 Some data to test");
+
+INSERT INTO bup_vp.t2 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("05 Some data to test");
+
+INSERT INTO bup_vp.t3 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("05 Some data to test");
+
+--echo 
+--echo con_bup: Show the data before we start backup
+SELECT * FROM bup_vp.t1;
+SELECT * FROM bup_vp.t2;
+SELECT * FROM bup_vp.t3;
+
+### CON 3 ###
+      --echo 
+      connection con_tx3;
+
+      --echo Scenario d) - commit after VP; tx not included in backup
+      --echo con_tx3: Start transaction but do not commit
+      BEGIN;
+          INSERT INTO bup_vp.t3 VALUES ("tx3: 06 Should NOT be in backup");
+
+### CON 1 ###
+  --echo 
+  connection con_tx1;
+
+  --echo Scenario b) - Commit in progress blocks CB; tx is included in backup
+  --echo con_tx1: Get a transaction going and stop in the middle of commit
+  BEGIN;
+      INSERT INTO bup_vp.t1 VALUES ("tx1: 06 Some data to test");
+
+      --echo con_tx1: Make commit stop in the middle of execution
+      # Will continue once backup has been blocked from setting CB
+      SET DEBUG_SYNC= 'within_ha_commit_trans SIGNAL commit_started
+                       WAIT_FOR complete_commit';
+      send COMMIT;
+
+### CON 2 ###
+    --echo 
+    connection con_tx2;
+
+    --echo Scenario c) - commit blocked by CB; tx not included in backup
+    --echo con_tx2: Wait until tx1 has started
+    SET DEBUG_SYNC= 'now WAIT_FOR commit_started';
+    --echo con_tx2: Start transaction but do not commit
+    BEGIN;
+        INSERT INTO bup_vp.t2 VALUES ("tx2: 06 Should NOT be in backup");
+    
+### CON BUP ###
+--echo 
+connection con_bup;
+
+# Backup will be blocked from setting CB by the ongoing commit in
+# con_tx1. Backup will signal con_tx1 that it has been blocked. The
+# commit will then finish, making backup able to set CB. When CB has
+# been set, tx2 will be signaled to try to commit. tx2 commit will be
+# blocked by the CB and send a signal that it has been blocked. CB is
+# then released, but backup is stopped immediately after releasing CB.
+# tx2 will now be able to complete the commit, and tx3 will issue and
+# complete a commit. Finally, backup is allowed to complete.
+
+--echo con_bup: Activate synchronization points for BACKUP.
+# Signal when backup is blocked by ongoing commit in con_tx1
+SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL sync_complete_commit';
+
+# tx1 commit is completed, so backup can set CB. Just before reaching
+# VP, signal tx2 should try to commit. Wait until tx2 signals it has
+# been blocked
+SET DEBUG_SYNC= 'before_backup_data_lock SIGNAL try_commit 
+                 WAIT_FOR commit_blocked';
+
+# tx2 commit has been blocked. Create VP and release CB, and then wait
+# while tx2 and tx2 commits.
+SET DEBUG_SYNC= 'after_backup_binlog SIGNAL commit_unblocked
+                 WAIT_FOR finish_bup';
+
+--echo con_bup: Backing up database -- will block with lock
+send BACKUP DATABASE bup_vp TO "bup_vp.bak";
+
+
+### CON SYNC ###
+--echo 
+connection con_sync;
+SET DEBUG_SYNC= 'now WAIT_FOR sync_complete_commit';
+--echo Backup has been blocked by ongoing commit
+
+--echo Check that con_tx1 has not committed; Should be 0 records
+SELECT * FROM bup_vp.t1 WHERE col_a like 'tx1%';
+--echo 
+
+SET DEBUG_SYNC= 'now SIGNAL complete_commit';
+
+### CON 1 ###
+  --echo 
+  connection con_tx1;
+  --echo con_tx1: Reap commit
+  reap;
+  --echo Check that con_tx1 has committed; Should be 1 record
+  SELECT * FROM bup_vp.t1 WHERE col_a like 'tx1%';
+  --echo 
+
+###########
+## Below this line happens after BACKUP has taken CB
+###########
+
+### CON 2 ###
+    --echo 
+    connection con_tx2;
+    --echo con_tx2: Commit request will be blocked by CB
+
+    # Wait for backup to set CB
+    SET DEBUG_SYNC= 'now WAIT_FOR try_commit';
+
+    # Signal to backup that the commit is blocked
+    SET DEBUG_SYNC= 'wait_if_global_read_lock SIGNAL sync_commit_blocked';
+
+    send COMMIT;
+
+    # Test is blocked on COMMIT until CB has been released
+
+### CON SYNC ###
+--echo 
+connection con_sync;
+SET DEBUG_SYNC= 'now WAIT_FOR sync_commit_blocked';
+
+--echo Check that con_tx2 has not committed; Should be 0 records
+SELECT * FROM bup_vp.t2 WHERE col_a like 'tx2%';
+--echo 
+
+SET DEBUG_SYNC= 'now SIGNAL commit_blocked';
+
+### CON 2 ###
+    --echo 
+    connection con_tx2;
+    --echo con_bup: Reap commit
+    # commit completes only after CB has been released
+    reap;
+
+    --echo con_tx2: Backup has now released CB.
+    --echo Check that con_tx2 has committed; Should be 1 record
+    SELECT * FROM bup_vp.t2 WHERE col_a like 'tx2%';
+    --echo 
+
+### CON 3 ###
+      --echo 
+      connection con_tx3;
+      --echo con_tx3: Backup has now released CB. Commit transaction
+
+      # Double-check that backup has reached sync point after CB release
+      SET DEBUG_SYNC= 'now WAIT_FOR commit_unblocked';
+      COMMIT;
+      SET DEBUG_SYNC= 'now SIGNAL finish_bup';
+
+
+### CON BUP ###
+--echo 
+connection con_bup;
+--echo con_bup: Reap backup
+--replace_column 1 #
+reap;
+
+###########
+## Verify results
+###########
+
+# Do selects to show that all changes got applied.
+--echo 
+--echo con_bup: Showing data after updates and backup
+SELECT * FROM bup_vp.t1;
+SELECT * FROM bup_vp.t2;
+SELECT * FROM bup_vp.t3;
+
+--echo con_bup: Dropping the database
+DROP TABLE bup_vp.t1;
+DROP TABLE bup_vp.t2;
+DROP TABLE bup_vp.t3;
+DROP DATABASE bup_vp;
+
+--echo con_bup: Restoring the database
+--replace_column 1 #
+RESTORE FROM "bup_vp.bak";
+
+--echo 
+--echo con_bup: Showing the data after restore (tx2 and tx3 should not be there)
+SELECT * FROM bup_vp.t1;
+SELECT * FROM bup_vp.t2;
+SELECT * FROM bup_vp.t3;
+
+--echo
+--echo Verifying results:
+--echo
+
+--echo T1 should have changes from con_tx1; Should be 1 record
+SELECT * FROM bup_vp.t1 WHERE col_a like 'tx1%';
+
+--echo 
+--echo T2 should not have the changes from con_tx2; Should be 0 records
+SELECT * FROM bup_vp.t2 WHERE col_a like 'tx2%';
+
+--echo 
+--echo T3 should not have the changes from con_tx3; Should be 0 records
+SELECT * FROM bup_vp.t3 WHERE col_a like 'tx3%';
+
+--echo 
+--echo con_bup: Cleanup
+DROP DATABASE bup_vp;
+
+remove_file $bdir/bup_vp.bak;
+SET DEBUG_SYNC= 'RESET';

=== modified file 'mysql-test/suite/backup/t/disabled.def'
--- a/mysql-test/suite/backup/t/disabled.def	2008-10-09 11:45:40 +0000
+++ b/mysql-test/suite/backup/t/disabled.def	2008-11-21 10:59:49 +0000
@@ -11,6 +11,8 @@
 ##############################################################################
 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_be                : Bug#38023 2008-07-16 rafal Test triggers valgrind warnings described in the bug
+#backup_no_be                : Bug#38023 2008-07-16 rafal Test triggers valgrind warnings described in the bug
 backup_no_data       : Bug#17823 2008-10-09 rafal Tests in main suite leave undeleted files causing this test to fail
 backup_ddl_blocker   : Bug#17823 2008-10-09 rafal Tests in main suite leave undeleted files causing this test to fail
+backup               : Bug#40807 2008-11-18 hakank Test fails on big-endian architecture
+backup_timeout       : Bug#40808 2008-11-18 hakank Test fails on big-endian architecture

=== modified file 'mysql-test/suite/backup_engines/include/backup_ptr_commit.inc'
--- a/mysql-test/suite/backup_engines/include/backup_ptr_commit.inc	2008-10-08 04:26:25 +0000
+++ b/mysql-test/suite/backup_engines/include/backup_ptr_commit.inc	2008-11-17 09:57:51 +0000
@@ -202,7 +202,7 @@ SELECT * FROM ptr.t3;
 
 --echo Perform restore operation
 --replace_column 1 #
-RESTORE FROM 'ptr_commit.bak';
+RESTORE FROM 'ptr_commit.bak' OVERWRITE;
 SHOW TABLES FROM ptr;
 SELECT * FROM ptr.t1;
 SELECT * FROM ptr.t2;

=== modified file 'mysql-test/suite/backup_engines/include/backup_ptr_objects.inc'
--- a/mysql-test/suite/backup_engines/include/backup_ptr_objects.inc	2008-10-08 04:26:25 +0000
+++ b/mysql-test/suite/backup_engines/include/backup_ptr_objects.inc	2008-11-12 17:42:23 +0000
@@ -38,9 +38,15 @@ SET timestamp=@a;
 # procedure p1, p2 and p3 are created in ptr_ob1 and p4 in ptr_ob2.
 #
 
+# Get rid of old objects in the databases.
+--disable_warnings
+DROP DATABASE IF EXISTS ptr_ob1;
+DROP DATABASE IF EXISTS ptr_ob2;
+--enable_warnings
+
 # Create database
-CREATE DATABASE IF NOT EXISTS ptr_ob1;
-CREATE DATABASE IF NOT EXISTS ptr_ob2;
+CREATE DATABASE ptr_ob1;
+CREATE DATABASE ptr_ob2;
 USE ptr_ob1;
 
 --echo **** Creating tables ****
@@ -109,9 +115,10 @@ BEGIN
 END;||
 delimiter ;||
 
-INSERT INTO ptr_ob1.t2 VALUES
-(NULL, 'Normal Insert1'),(NULL, 'Normal Insert2'),
-(NULL, 'Normal Insert3'),(NULL, 'Normal Insert4');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert1');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert2');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert3');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert4');
 SELECT * FROM ptr_ob1.t2;
 SELECT * FROM ptr_ob1.t3;
 

=== modified file 'mysql-test/suite/backup_engines/r/backup_online_testing.result'
--- a/mysql-test/suite/backup_engines/r/backup_online_testing.result	2008-06-30 19:40:33 +0000
+++ b/mysql-test/suite/backup_engines/r/backup_online_testing.result	2008-11-19 22:01:28 +0000
@@ -1135,3 +1135,4 @@ COUNT(*)
 ***  DROP bup_online DATABASE ****
 
 DROP DATABASE bup_online;
+SET DEBUG_SYNC= 'RESET';

=== modified file 'mysql-test/suite/backup_engines/r/backup_ptr_commit_mixed.result'
--- a/mysql-test/suite/backup_engines/r/backup_ptr_commit_mixed.result	2008-10-08 04:26:25 +0000
+++ b/mysql-test/suite/backup_engines/r/backup_ptr_commit_mixed.result	2008-11-17 09:57:51 +0000
@@ -304,7 +304,7 @@ id	name
 Perform Restore and Recover committed data using mysqlbinlog position
 after backup.
 Perform restore operation
-RESTORE FROM 'ptr_commit.bak';
+RESTORE FROM 'ptr_commit.bak' OVERWRITE;
 backup_id
 #
 SHOW TABLES FROM ptr;

=== modified file 'mysql-test/suite/backup_engines/r/backup_ptr_commit_row.result'
--- a/mysql-test/suite/backup_engines/r/backup_ptr_commit_row.result	2008-10-08 04:26:25 +0000
+++ b/mysql-test/suite/backup_engines/r/backup_ptr_commit_row.result	2008-11-17 09:57:51 +0000
@@ -304,7 +304,7 @@ id	name
 Perform Restore and Recover committed data using mysqlbinlog position
 after backup.
 Perform restore operation
-RESTORE FROM 'ptr_commit.bak';
+RESTORE FROM 'ptr_commit.bak' OVERWRITE;
 backup_id
 #
 SHOW TABLES FROM ptr;

=== modified file 'mysql-test/suite/backup_engines/r/backup_ptr_commit_stmt.result'
--- a/mysql-test/suite/backup_engines/r/backup_ptr_commit_stmt.result	2008-10-08 04:26:25 +0000
+++ b/mysql-test/suite/backup_engines/r/backup_ptr_commit_stmt.result	2008-11-17 09:57:51 +0000
@@ -304,7 +304,7 @@ id	name
 Perform Restore and Recover committed data using mysqlbinlog position
 after backup.
 Perform restore operation
-RESTORE FROM 'ptr_commit.bak';
+RESTORE FROM 'ptr_commit.bak' OVERWRITE;
 backup_id
 #
 SHOW TABLES FROM ptr;

=== modified file 'mysql-test/suite/backup_engines/r/backup_ptr_objects_mixed.result'
--- a/mysql-test/suite/backup_engines/r/backup_ptr_objects_mixed.result	2008-10-08 04:26:25 +0000
+++ b/mysql-test/suite/backup_engines/r/backup_ptr_objects_mixed.result	2008-11-12 17:42:23 +0000
@@ -14,8 +14,10 @@ till point of backup and after backup.
 
 SET @a=UNIX_TIMESTAMP("2010-01-21 15:32:22");
 SET timestamp=@a;
-CREATE DATABASE IF NOT EXISTS ptr_ob1;
-CREATE DATABASE IF NOT EXISTS ptr_ob2;
+DROP DATABASE IF EXISTS ptr_ob1;
+DROP DATABASE IF EXISTS ptr_ob2;
+CREATE DATABASE ptr_ob1;
+CREATE DATABASE ptr_ob2;
 USE ptr_ob1;
 **** Creating tables ****
 CREATE TABLE ptr_ob1.t1(
@@ -102,9 +104,10 @@ CREATE TRIGGER ptr_ob1.trg2 AFTER INSERT
 BEGIN
 INSERT INTO ptr_ob1.t3 VALUES(NULL, 'trigger fired for AFTER INSERT', 100);
 END;||
-INSERT INTO ptr_ob1.t2 VALUES
-(NULL, 'Normal Insert1'),(NULL, 'Normal Insert2'),
-(NULL, 'Normal Insert3'),(NULL, 'Normal Insert4');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert1');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert2');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert3');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert4');
 SELECT * FROM ptr_ob1.t2;
 id	data
 1	Normal Insert1

=== modified file 'mysql-test/suite/backup_engines/r/backup_ptr_objects_row.result'
--- a/mysql-test/suite/backup_engines/r/backup_ptr_objects_row.result	2008-10-08 04:26:25 +0000
+++ b/mysql-test/suite/backup_engines/r/backup_ptr_objects_row.result	2008-11-12 17:42:23 +0000
@@ -14,8 +14,10 @@ till point of backup and after backup.
 
 SET @a=UNIX_TIMESTAMP("2010-01-21 15:32:22");
 SET timestamp=@a;
-CREATE DATABASE IF NOT EXISTS ptr_ob1;
-CREATE DATABASE IF NOT EXISTS ptr_ob2;
+DROP DATABASE IF EXISTS ptr_ob1;
+DROP DATABASE IF EXISTS ptr_ob2;
+CREATE DATABASE ptr_ob1;
+CREATE DATABASE ptr_ob2;
 USE ptr_ob1;
 **** Creating tables ****
 CREATE TABLE ptr_ob1.t1(
@@ -102,9 +104,10 @@ CREATE TRIGGER ptr_ob1.trg2 AFTER INSERT
 BEGIN
 INSERT INTO ptr_ob1.t3 VALUES(NULL, 'trigger fired for AFTER INSERT', 100);
 END;||
-INSERT INTO ptr_ob1.t2 VALUES
-(NULL, 'Normal Insert1'),(NULL, 'Normal Insert2'),
-(NULL, 'Normal Insert3'),(NULL, 'Normal Insert4');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert1');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert2');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert3');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert4');
 SELECT * FROM ptr_ob1.t2;
 id	data
 1	Normal Insert1

=== modified file 'mysql-test/suite/backup_engines/r/backup_ptr_objects_stmt.result'
--- a/mysql-test/suite/backup_engines/r/backup_ptr_objects_stmt.result	2008-10-08 04:26:25 +0000
+++ b/mysql-test/suite/backup_engines/r/backup_ptr_objects_stmt.result	2008-11-12 17:42:23 +0000
@@ -14,8 +14,10 @@ till point of backup and after backup.
 
 SET @a=UNIX_TIMESTAMP("2010-01-21 15:32:22");
 SET timestamp=@a;
-CREATE DATABASE IF NOT EXISTS ptr_ob1;
-CREATE DATABASE IF NOT EXISTS ptr_ob2;
+DROP DATABASE IF EXISTS ptr_ob1;
+DROP DATABASE IF EXISTS ptr_ob2;
+CREATE DATABASE ptr_ob1;
+CREATE DATABASE ptr_ob2;
 USE ptr_ob1;
 **** Creating tables ****
 CREATE TABLE ptr_ob1.t1(
@@ -102,9 +104,10 @@ CREATE TRIGGER ptr_ob1.trg2 AFTER INSERT
 BEGIN
 INSERT INTO ptr_ob1.t3 VALUES(NULL, 'trigger fired for AFTER INSERT', 100);
 END;||
-INSERT INTO ptr_ob1.t2 VALUES
-(NULL, 'Normal Insert1'),(NULL, 'Normal Insert2'),
-(NULL, 'Normal Insert3'),(NULL, 'Normal Insert4');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert1');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert2');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert3');
+INSERT INTO ptr_ob1.t2 VALUES (NULL, 'Normal Insert4');
 SELECT * FROM ptr_ob1.t2;
 id	data
 1	Normal Insert1

=== added file 'mysql-test/suite/backup_engines/r/backup_tmp_tables.result'
--- a/mysql-test/suite/backup_engines/r/backup_tmp_tables.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup_engines/r/backup_tmp_tables.result	2008-11-17 09:57:51 +0000
@@ -0,0 +1,58 @@
+SHOW VARIABLES LIKE 'storage_engine';
+Variable_name	Value
+storage_engine	#
+** Pre-cleanup
+DROP DATABASE IF EXISTS db;
+** Create a database
+CREATE DATABASE db;
+USE db;
+** Create regular tables
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a char(1));
+** Create a view
+CREATE VIEW v1 AS SELECT * FROM t1;
+** Store table's definition for later check
+** Insert some data into the tables
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES ('x');
+** Create temporary tables with the same name, but different layout
+** and using different storage engines
+CREATE TEMPORARY TABLE t1 (b text, c int) ENGINE=MyISAM;
+CREATE TEMPORARY TABLE t2 (b int, c blob) ENGINE=InnoDB;
+** Insert data into the temporary tables
+INSERT INTO t1 VALUES ('foo', 2);
+INSERT INTO t2 VALUES (3, 'bar');
+** Backup database
+BACKUP DATABASE db TO 'db.bkp';
+backup_id
+#
+** Drop and restore the database
+DROP TABLE t1;
+DROP TABLE t2;
+RESTORE FROM 'db.bkp' OVERWRITE;
+backup_id
+#
+** Check definitions of the tables after restore
+table_t1
+0
+table_t2
+0
+** Checking data after restore
+SELECT * FROM t1;
+a
+1
+SELECT * FROM t2;
+a
+x
+SELECT * FROM v1;
+a
+1
+** Checking if restored table is seen from other connection
+SELECT * FROM db.t1;
+a
+1
+SELECT * FROM db.t2;
+a
+x
+** Cleanup
+DROP DATABASE db;

=== modified file 'mysql-test/suite/backup_engines/t/backup_online_testing.test'
--- a/mysql-test/suite/backup_engines/t/backup_online_testing.test	2008-06-30 19:40:33 +0000
+++ b/mysql-test/suite/backup_engines/t/backup_online_testing.test	2008-11-19 22:01:28 +0000
@@ -1152,3 +1152,4 @@ DROP DATABASE bup_online;
 
 remove_file $MYSQLTEST_VARDIR/master-data/bup_online.bak;
 
+SET DEBUG_SYNC= 'RESET';

=== added file 'mysql-test/suite/backup_engines/t/backup_tmp_tables.test'
--- a/mysql-test/suite/backup_engines/t/backup_tmp_tables.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup_engines/t/backup_tmp_tables.test	2008-11-17 09:57:51 +0000
@@ -0,0 +1,92 @@
+#
+# Test that BACKUP works correctly in the presence of temporary tables
+# with the same names as tables being backed-up (BUG#33574, BUG#34903).
+#
+
+--source include/not_embedded.inc
+--source include/have_innodb.inc
+--source suite/backup_engines/include/backup_engine.inc
+
+let $bdir= `SELECT @@backupdir`;
+
+--echo ** Pre-cleanup
+--disable_warnings
+DROP DATABASE IF EXISTS db;
+--error 0,1
+--remove_file $bdir/db.bkp
+--enable_warnings
+
+--echo ** Create a database
+CREATE DATABASE db;
+USE db;
+
+--echo ** Create regular tables
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a char(1));
+
+--echo ** Create a view
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+--echo ** Store table's definition for later check
+let $stmt1= query_get_value(SHOW CREATE TABLE t1, Create Table, 1);
+let $stmt2= query_get_value(SHOW CREATE TABLE t2, Create Table, 1);
+
+--echo ** Insert some data into the tables
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES ('x');
+
+--echo ** Create temporary tables with the same name, but different layout
+--echo ** and using different storage engines
+CREATE TEMPORARY TABLE t1 (b text, c int) ENGINE=MyISAM;
+CREATE TEMPORARY TABLE t2 (b int, c blob) ENGINE=InnoDB;
+
+--echo ** Insert data into the temporary tables
+INSERT INTO t1 VALUES ('foo', 2);
+INSERT INTO t2 VALUES (3, 'bar');
+
+--echo ** Backup database
+--replace_column 1 #
+BACKUP DATABASE db TO 'db.bkp';
+
+--echo ** Drop and restore the database
+DROP TABLE t1;
+DROP TABLE t2;
+--replace_column 1 #
+RESTORE FROM 'db.bkp' OVERWRITE;
+
+#
+# Note: Above DROP TABLE statements should be removed once BUG#30099 is fixed.
+#
+
+--echo ** Check definitions of the tables after restore
+let $stmt1a= query_get_value(SHOW CREATE TABLE t1, Create Table, 1);
+let $stmt2a= query_get_value(SHOW CREATE TABLE t2, Create Table, 1);
+--disable_query_log
+--eval SELECT strcmp("$stmt1","$stmt1a") AS table_t1
+--eval SELECT strcmp("$stmt2","$stmt2a") AS table_t2
+--enable_query_log
+
+#
+# Note: The above tests using strcmp() might be too sensitive, although they 
+# work now. Theoreticaly the details of the CREATE TABLE statement produced by 
+# SHOW CREATE TABLE could be different even if RESTORE works ok. If you see 
+# result missmatch here, analyse carefully what are the differences before 
+# reporting a bug. The main purpose of above checks is to  ensure that RESTORE 
+# haven't wrongly captured definitions of the temporary tables instead of the 
+# regular ones.
+#
+
+--echo ** Checking data after restore
+SELECT * FROM t1;
+SELECT * FROM t2;
+SELECT * FROM v1;
+
+--echo ** Checking if restored table is seen from other connection
+connect (A, localhost, root,,);
+--connection A
+SELECT * FROM db.t1;
+SELECT * FROM db.t2;
+
+--echo ** Cleanup
+DROP DATABASE db;
+--remove_file $bdir/db.bkp

=== added file 'mysql-test/suite/backup_engines/t/disabled.def'
--- a/mysql-test/suite/backup_engines/t/disabled.def	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup_engines/t/disabled.def	2008-11-18 21:10:05 +0000
@@ -0,0 +1,13 @@
+##############################################################################
+#
+#  List the test cases that are to be disabled temporarily.
+#
+#  Separate the test case name and the comment with ':'.
+#
+#    <testcasename> : BUG#<xxxx> <date disabled> <disabler> <comment>
+#
+#  Do not use any TAB characters for whitespace.
+#
+##############################################################################
+backup_ptr_mixed     : Bug#37281 2008-11-18 hakank Dates in Falcon on big-endian have wrong result.
+backup_ptr_row       : Bug#37281 2008-11-18 hakank Dates in Falcon on big-endian have wrong result.

=== renamed file 'mysql-test/suite/falcon/r/falcon_bug_28095_I.result' => 'mysql-test/suite/falcon/r/falcon_bug_28095.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_28095_I.result	2007-09-20 15:44:25 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_28095.result	2008-11-04 15:22:06 +0000
@@ -1,15 +1,35 @@
-SET STORAGE_ENGINE = Falcon;
-*** Bug #126: First phase ***
-*** Also covering bug #113 ***
+*** Bug #28095: First phase ***
+SET @@storage_engine = 'Falcon';
 DROP TABLE IF EXISTS t1;
 DROP TABLE IF EXISTS t2;
 CREATE TABLE t1 (a int);
 INSERT INTO t1 VALUES (1);
 INSERT INTO t1 VALUES (2);
 INSERT INTO t1 VALUES (3);
-SELECT * FROM t1;
+SELECT * FROM t1 ORDER BY a;
 a
 1
 2
 3
 CREATE TABLE t2 (b int);
+SELECT @@GLOBAL.falcon_debug_mask;
+@@GLOBAL.falcon_debug_mask
+0
+SET GLOBAL falcon_debug_mask = 4096;
+SELECT @@GLOBAL.falcon_debug_mask;
+@@GLOBAL.falcon_debug_mask
+4096
+*** Bug #28095: Second phase ***
+SELECT * FROM t1 ORDER BY a;
+a
+1
+2
+3
+SELECT count(*) FROM t1;
+count(*)
+3
+SELECT @@GLOBAL.falcon_debug_mask;
+@@GLOBAL.falcon_debug_mask
+0
+DROP TABLE t1;
+DROP TABLE t2;

=== removed file 'mysql-test/suite/falcon/r/falcon_bug_28095_II.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_28095_II.result	2008-03-28 17:13:51 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_28095_II.result	1970-01-01 00:00:00 +0000
@@ -1,9 +0,0 @@
-*** Bug #126: Second phase ***
-*** Also test for bug #123 ***
-SET @@storage_engine = Falcon;
-SELECT * FROM t1;
-a
-1
-2
-3
-DROP TABLE t1, t2;

=== added file 'mysql-test/suite/falcon/r/falcon_bug_30124-big.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_30124-big.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_30124-big.result	2008-10-28 19:32:35 +0000
@@ -0,0 +1,34 @@
+*** Bug #30124 ***
+SET @@storage_engine = 'Falcon';
+DROP TABLE IF EXISTS t1;
+DROP PROCEDURE IF EXISTS p1;
+SET @@autocommit=0;
+CREATE TABLE t1 (a int auto_increment PRIMARY KEY, b int);
+PREPARE stmt1 FROM 'INSERT INTO t1 (b) VALUES (?)';
+CREATE PROCEDURE p1()
+BEGIN
+SET @i = 0;
+SET @v = 0;
+WHILE @i < 1000000 DO
+SET @a = @v;
+EXECUTE stmt1 USING @a;
+SET @v = @v + 1;
+IF @v = 10 THEN
+SET @v = 0;
+END IF;
+SET @i = @i + 1;
+END WHILE;
+END;//
+CALL p1;
+COMMIT;
+SET @@autocommit = 1;
+UPDATE t1 SET b = 5 WHERE b = 3;
+SELECT count(*) FROM t1;
+count(*)
+1000000
+SELECT count(*) FROM t1 WHERE b = 5;
+count(*)
+200000
+DEALLOCATE PREPARE stmt1;
+DROP TABLE t1;
+DROP PROCEDURE p1;

=== modified file 'mysql-test/suite/falcon/r/falcon_bug_30124.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_30124.result	2007-09-20 15:44:25 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_30124.result	2008-10-28 19:32:35 +0000
@@ -9,7 +9,7 @@ CREATE PROCEDURE p1()
 BEGIN
 SET @i = 0;
 SET @v = 0;
-WHILE @i < 500000 DO
+WHILE @i < 100000 DO
 SET @a = @v;
 EXECUTE stmt1 USING @a;
 SET @v = @v + 1;
@@ -25,10 +25,10 @@ SET @@autocommit = 1;
 UPDATE t1 SET b = 5 WHERE b = 3;
 SELECT count(*) FROM t1;
 count(*)
-500000
+100000
 SELECT count(*) FROM t1 WHERE b = 5;
 count(*)
-100000
+20000
 DEALLOCATE PREPARE stmt1;
 DROP TABLE t1;
 DROP PROCEDURE p1;

=== added file 'mysql-test/suite/falcon/r/falcon_bug_38186.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_38186.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_38186.result	2008-10-31 00:29:13 +0000
@@ -0,0 +1,2 @@
+*** Bug #38186 ***
+SET @@storage_engine = 'Falcon';

=== added file 'mysql-test/suite/falcon/r/falcon_bug_39708.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_39708.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_39708.result	2008-10-29 11:41:14 +0000
@@ -0,0 +1,6 @@
+CREATE TABLE t1(a VARCHAR(140) CHARACTER SET utf8, KEY(a)) ENGINE=falcon;
+ERROR 42000: Specified key was too long; max key length is 540 bytes
+SHOW WARNINGS;
+Level	Code	Message
+Error	1071	Specified key was too long; max key length is 540 bytes
+Error	1005	Can't create table 'test.t1' (errno: 213)

=== added file 'mysql-test/suite/falcon/r/falcon_bug_40130.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_40130.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_40130.result	2008-11-05 15:04:45 +0000
@@ -0,0 +1,398 @@
+*** Bug #40130 ***
+SET @@storage_engine = 'Falcon';
+DROP TABLE IF EXISTS table10;
+CREATE TABLE table10 (`time_key` time, key (`time_key` ));
+INSERT INTO table10 VALUES ('23:43:55');
+INSERT INTO table10 VALUES ('03:18:59');
+INSERT INTO table10 VALUES ('05:05:23');
+INSERT INTO table10 VALUES ('09:20:40');
+INSERT INTO table10 VALUES ('22:32:50');
+INSERT INTO table10 VALUES ('07:41:31');
+INSERT INTO table10 VALUES ('10:52:13');
+INSERT INTO table10 VALUES ('12:40:54');
+INSERT INTO table10 VALUES ('10:33:25');
+INSERT INTO table10 VALUES ('22:11:46');
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '09:11:23' WHERE `time_key` < '16:23:56';
+INSERT INTO table10 VALUES ( '20:25:18' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '10:33:25' WHERE `time_key` > '22:11:46';
+INSERT INTO table10 VALUES ( '17:58:48' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '00:16:10' );
+UPDATE table10 SET `time_key` = '16:05:35' WHERE `time_key` > '16:57:24';
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '20:24:01' );
+INSERT INTO table10 VALUES ( '18:37:59' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '21:05:17' WHERE `time_key` < '06:07:07';
+INSERT INTO table10 VALUES ( '00:05:40' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '13:34:36' );
+INSERT INTO table10 VALUES ( '22:35:15' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '09:32:02' );
+INSERT INTO table10 VALUES ( '12:02:39' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '19:22:23' WHERE `time_key` < '03:39:55';
+UPDATE table10 SET `time_key` = '13:45:38' WHERE `time_key` < '03:52:41';
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '21:57:00' WHERE `time_key` < '11:37:04';
+INSERT INTO table10 VALUES ( '18:56:03' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '21:46:34' );
+INSERT INTO table10 VALUES ( '00:46:37' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '11:54:45' );
+INSERT INTO table10 VALUES ( '11:00:16' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '04:41:27' WHERE `time_key` > '05:45:30';
+INSERT INTO table10 VALUES ( '05:55:02' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '02:51:17' WHERE `time_key` < '05:33:58';
+INSERT INTO table10 VALUES ( '06:07:14' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '19:17:13' );
+UPDATE table10 SET `time_key` = '14:23:25' WHERE `time_key` < '18:44:25';
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '01:54:06' );
+INSERT INTO table10 VALUES ( '05:36:42' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '04:04:15' WHERE `time_key` < '17:09:11';
+INSERT INTO table10 VALUES ( '13:22:58' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '03:45:01' WHERE `time_key` < '01:02:29';
+INSERT INTO table10 VALUES ( '14:45:34' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '12:33:12' );
+INSERT INTO table10 VALUES ( '21:40:27' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '05:05:45' );
+INSERT INTO table10 VALUES ( '01:21:15' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '01:43:44' WHERE `time_key` > '18:44:54';
+UPDATE table10 SET `time_key` = '16:00:25' WHERE `time_key` > '17:37:45';
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '09:17:29' );
+UPDATE table10 SET `time_key` = '00:32:27' WHERE `time_key` < '19:55:22';
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '00:01:27' WHERE `time_key` < '23:49:20';
+INSERT INTO table10 VALUES ( '11:10:06' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '21:52:14' WHERE `time_key` > '00:54:57';
+INSERT INTO table10 VALUES ( '10:32:20' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '05:48:51' WHERE `time_key` < '05:53:48';
+UPDATE table10 SET `time_key` = '04:11:47' WHERE `time_key` > '14:02:03';
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '20:58:47' );
+INSERT INTO table10 VALUES ( '06:58:04' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '14:41:45' );
+UPDATE table10 SET `time_key` = '00:45:47' WHERE `time_key` < '21:51:00';
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '09:01:24' );
+INSERT INTO table10 VALUES ( '07:07:37' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '06:25:00' );
+INSERT INTO table10 VALUES ( '05:47:01' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '12:31:51' WHERE `time_key` > '04:34:05';
+INSERT INTO table10 VALUES ( '01:31:26' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '01:46:22' );
+INSERT INTO table10 VALUES ( '01:14:58' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '04:09:31' );
+UPDATE table10 SET `time_key` = '08:28:13' WHERE `time_key` > '14:50:18';
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '11:19:43' WHERE `time_key` < '04:30:14';
+INSERT INTO table10 VALUES ( '20:03:24' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '14:40:32' WHERE `time_key` < '15:30:08';
+UPDATE table10 SET `time_key` = '03:13:02' WHERE `time_key` < '21:47:42';
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '20:37:56' );
+UPDATE table10 SET `time_key` = '15:51:19' WHERE `time_key` < '01:39:43';
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '07:15:18' WHERE `time_key` > '05:37:40';
+INSERT INTO table10 VALUES ( '18:47:30' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '13:32:24' WHERE `time_key` > '23:38:12';
+INSERT INTO table10 VALUES ( '23:32:39' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '22:01:18' WHERE `time_key` < '17:51:48';
+INSERT INTO table10 VALUES ( '11:41:29' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '15:45:55' WHERE `time_key` > '04:03:52';
+UPDATE table10 SET `time_key` = '05:43:47' WHERE `time_key` < '07:29:01';
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '23:44:48' WHERE `time_key` < '00:33:42';
+UPDATE table10 SET `time_key` = '08:56:04' WHERE `time_key` > '12:16:41';
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '19:23:41' );
+INSERT INTO table10 VALUES ( '18:44:20' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '00:40:04' WHERE `time_key` > '11:34:06';
+UPDATE table10 SET `time_key` = '23:45:59' WHERE `time_key` < '09:44:50';
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '18:54:59' WHERE `time_key` < '15:46:02';
+INSERT INTO table10 VALUES ( '17:37:41' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '17:08:04' WHERE `time_key` < '14:11:50';
+UPDATE table10 SET `time_key` = '21:33:59' WHERE `time_key` > '17:44:43';
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '03:50:15' WHERE `time_key` > '19:35:18';
+UPDATE table10 SET `time_key` = '23:15:47' WHERE `time_key` < '12:18:46';
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '22:50:01' );
+INSERT INTO table10 VALUES ( '17:29:53' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '21:33:30' );
+INSERT INTO table10 VALUES ( '06:27:52' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '07:49:31' );
+INSERT INTO table10 VALUES ( '21:31:25' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '13:50:22' );
+INSERT INTO table10 VALUES ( '15:13:07' );
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '14:06:24' );
+INSERT INTO table10 VALUES ( '19:10:11' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '05:03:39' WHERE `time_key` > '11:46:31';
+INSERT INTO table10 VALUES ( '04:35:34' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '14:37:01' WHERE `time_key` < '02:11:03';
+INSERT INTO table10 VALUES ( '10:52:22' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '15:37:40' WHERE `time_key` > '11:19:00';
+INSERT INTO table10 VALUES ( '08:46:29' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '07:59:59' WHERE `time_key` < '05:27:20';
+UPDATE table10 SET `time_key` = '00:45:15' WHERE `time_key` < '20:07:08';
+COMMIT;
+START TRANSACTION;
+INSERT INTO table10 VALUES ( '00:51:31' );
+UPDATE table10 SET `time_key` = '10:00:58' WHERE `time_key` < '16:41:45';
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '13:49:37' WHERE `time_key` > '10:40:48';
+INSERT INTO table10 VALUES ( '05:16:25' );
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '14:46:15' WHERE `time_key` < '12:48:22';
+UPDATE table10 SET `time_key` = '05:50:46' WHERE `time_key` < '07:58:43';
+COMMIT;
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '00:11:06' WHERE `time_key` < '16:39:47';
+UPDATE table10 SET `time_key` = '04:13:41' WHERE `time_key` < '14:55:39';
+COMMIT;
+SELECT * FROM table10;
+time_key
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+04:13:41
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '00:28:04' WHERE `time_key` < '09:58:46';
+UPDATE table10 SET `time_key` = '04:56:25' WHERE `time_key` > '09:26:08';
+COMMIT;
+SELECT * FROM table10;
+time_key
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+00:28:04
+DROP TABLE table10;

=== added file 'mysql-test/suite/falcon/r/falcon_bug_40158.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_40158.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_40158.result	2008-11-05 14:51:37 +0000
@@ -0,0 +1,34 @@
+*** Bug #40158 ***
+SET @@storage_engine = 'Falcon';
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (`"strangename"` int);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
+"strangename"
+1
+SELECT `"strangename"` FROM t1;
+"strangename"
+1
+DROP TABLE t1;
+SET LOCAL SQL_MODE=ANSI_QUOTES;
+CREATE TABLE t1 ("""strangename""" int);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
+"strangename"
+1
+SELECT """strangename""" FROM t1;
+"strangename"
+1
+DROP TABLE t1;
+CREATE TABLE t1 (`""strangename""` int);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
+""strangename""
+1
+SELECT `""strangename""` FROM t1;
+""strangename""
+1
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+1
+DROP TABLE t1;

=== modified file 'mysql-test/suite/falcon/t/disabled.def'
--- a/mysql-test/suite/falcon/t/disabled.def	2008-09-11 16:28:29 +0000
+++ b/mysql-test/suite/falcon/t/disabled.def	2008-11-04 15:22:06 +0000
@@ -10,6 +10,4 @@
 #
 ##############################################################################
 
-falcon_bug_28095_I  : Bug#xxxxx 2008-04-22 hakank Disabled until soft restart is in main tree
-falcon_bug_28095_II : Bug#xxxxx 2008-03-22 hakank Disabled until soft restart is in main tree
 falcon_bug_32398 : HF disabled until new fix for this bug is developed

=== renamed file 'mysql-test/suite/falcon/t/falcon_bug_28095_I.test' => 'mysql-test/suite/falcon/t/falcon_bug_28095.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_28095_I.test	2007-09-29 04:30:42 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_28095.test	2008-11-13 14:55:42 +0000
@@ -1,20 +1,62 @@
 --source include/have_falcon.inc
-SET STORAGE_ENGINE = Falcon;
+
+#
+# Bug #28095: Falcon Drop table causes crash
 #
-# Mantis bug #126 first phase: Drop table causes crash
-# Mantis bug #113: JStar is crashing on shutdown
+# Note: This test consists of two phases involving a "soft"
+#    server restart with --shutdown_server. We do the
+#    restart with the help of include/restart_mysqld.inc.
 #
---echo *** Bug #126: First phase ***
---echo *** Also covering bug #113 ***
+--echo *** Bug #28095: First phase ***
+
+# ----------------------------------------------------- #
+# --- Initialisation                                --- #
+# ----------------------------------------------------- #
+let $engine = 'Falcon';
+eval SET @@storage_engine = $engine;
+
 --disable_warnings
 DROP TABLE IF EXISTS t1;
 DROP TABLE IF EXISTS t2;
 --enable_warnings
 
 CREATE TABLE t1 (a int);
+
+# ----------------------------------------------------- #
+# --- Test                                          --- #
+# ----------------------------------------------------- #
 INSERT INTO t1 VALUES (1);
 INSERT INTO t1 VALUES (2);
 INSERT INTO t1 VALUES (3);
-SELECT * FROM t1;
+SELECT * FROM t1 ORDER BY a;
 
 CREATE TABLE t2 (b int);
+
+#
+# We set a global variable to make sure that the
+# following restart really works. Global variables
+# should be resetted after a server restart.
+#
+SELECT @@GLOBAL.falcon_debug_mask;
+SET GLOBAL falcon_debug_mask = 4096;
+SELECT @@GLOBAL.falcon_debug_mask;
+
+# ----------------------------------------------------- #
+# --- Restart server                                --- #
+# ----------------------------------------------------- #
+--source include/restart_mysqld.inc
+
+--echo *** Bug #28095: Second phase ***
+SELECT * FROM t1 ORDER BY a;
+
+# ----------------------------------------------------- #
+# --- Check                                         --- #
+# ----------------------------------------------------- #
+SELECT count(*) FROM t1;
+SELECT @@GLOBAL.falcon_debug_mask;
+
+# ----------------------------------------------------- #
+# --- Final cleanup                                 --- #
+# ----------------------------------------------------- #
+DROP TABLE t1;
+DROP TABLE t2;

=== removed file 'mysql-test/suite/falcon/t/falcon_bug_28095_II-master.opt'
--- a/mysql-test/suite/falcon/t/falcon_bug_28095_II-master.opt	2008-03-28 17:13:51 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_28095_II-master.opt	1970-01-01 00:00:00 +0000
@@ -1 +0,0 @@
---sql_mode=''

=== removed file 'mysql-test/suite/falcon/t/falcon_bug_28095_II.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_28095_II.test	2008-03-28 17:13:51 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_28095_II.test	1970-01-01 00:00:00 +0000
@@ -1,11 +0,0 @@
---source include/have_falcon.inc
-#
-# Mantis bug #126 second phase: Drop table causes crash
-# Mantis bug #123: Table cannot be read after restarting mysqld
-#
---echo *** Bug #126: Second phase ***
---echo *** Also test for bug #123 ***
-SET @@storage_engine = Falcon;
-
-SELECT * FROM t1;
-DROP TABLE t1, t2;

=== added file 'mysql-test/suite/falcon/t/falcon_bug_30124-big.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_30124-big.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_30124-big.test	2008-10-28 19:32:35 +0000
@@ -0,0 +1,73 @@
+--source include/have_falcon.inc
+--source include/big_test.inc
+
+#
+# Bug #30124: UPDATE has unacceptable performance
+#
+#    This update should take just a few seconds.
+#    It must unlock 900,000 records after updating only 100,000.
+#    With the bug, it took 30 to 60 minutes.
+#    It takes a while to build the file though.
+#
+--echo *** Bug #30124 ***
+
+# ----------------------------------------------------- #
+# --- Initialisation                                --- #
+# ----------------------------------------------------- #
+let $engine = 'Falcon';
+eval SET @@storage_engine = $engine;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP PROCEDURE IF EXISTS p1;
+--enable_warnings
+
+SET @@autocommit=0;
+
+CREATE TABLE t1 (a int auto_increment PRIMARY KEY, b int);
+
+PREPARE stmt1 FROM 'INSERT INTO t1 (b) VALUES (?)';
+
+DELIMITER //;
+CREATE PROCEDURE p1()
+BEGIN
+  SET @i = 0;
+  SET @v = 0;
+
+  WHILE @i < 1000000 DO
+    SET @a = @v;
+
+    EXECUTE stmt1 USING @a;
+
+    SET @v = @v + 1;
+    IF @v = 10 THEN
+      SET @v = 0;
+    END IF;
+
+    SET @i = @i + 1;
+  END WHILE;
+END;//
+DELIMITER ;//
+
+CALL p1;
+COMMIT;
+
+# ----------------------------------------------------- #
+# --- Test                                          --- #
+# ----------------------------------------------------- #
+SET @@autocommit = 1;
+UPDATE t1 SET b = 5 WHERE b = 3;
+
+# ----------------------------------------------------- #
+# --- Check                                         --- #
+# ----------------------------------------------------- #
+SELECT count(*) FROM t1;
+SELECT count(*) FROM t1 WHERE b = 5;
+
+
+# ----------------------------------------------------- #
+# --- Final cleanup                                 --- #
+# ----------------------------------------------------- #
+DEALLOCATE PREPARE stmt1;
+DROP TABLE t1;
+DROP PROCEDURE p1;

=== modified file 'mysql-test/suite/falcon/t/falcon_bug_30124.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_30124.test	2007-09-29 04:30:42 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_30124.test	2008-10-28 19:32:35 +0000
@@ -1,14 +1,15 @@
 --source include/have_falcon.inc
+
 #
 # Bug #30124: UPDATE has unacceptable performance
 #
-# This update should take just a few seconds.
-# It must unlock 900,000 records after updating only 100,000.
-# With the bug, it took 30 to 60 minutes.
-# It takes a while to build the file though.
+#    This update should take just a few seconds.
+#    It must unlock 900,000 records after updating only 100,000.
+#    With the bug, it took 30 to 60 minutes.
+#    It takes a while to build the file though.
 #
-# Note: original test case is with loop count of 1 mio.
-#       Lowered to 500k due to long run time.
+# Note: Original test case is with loop count of 1 mio.
+#       Lowered to 100k due to long run time on slow machines.
 --echo *** Bug #30124 ***
 
 # ----------------------------------------------------- #
@@ -34,7 +35,7 @@ BEGIN
   SET @i = 0;
   SET @v = 0;
 
-  WHILE @i < 500000 DO
+  WHILE @i < 100000 DO
     SET @a = @v;
 
     EXECUTE stmt1 USING @a;

=== added file 'mysql-test/suite/falcon/t/falcon_bug_38186.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_38186.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_38186.test	2008-10-31 00:29:13 +0000
@@ -0,0 +1,29 @@
+--source include/have_falcon.inc
+#
+# Bug #38186: 
+# CREATE TABLESPACE can fail when invoked immediately following a
+# DROP TABLESPACE statement that used the same tablespace name.
+#
+--echo *** Bug #38186 ***
+
+# ----------------------------------------------------- #
+# --- Initialisation                                --- #
+# ----------------------------------------------------- #
+let $engine = 'Falcon';
+eval SET @@storage_engine = $engine;
+# ----------------------------------------------------- #
+# --- Test                                          --- #
+# ----------------------------------------------------- #
+--disable_query_log
+let $i = 100;
+while($i)
+{
+  eval CREATE TABLESPACE ts ADD DATAFILE 'file.fts' ENGINE = $engine;
+  CREATE TABLE t(i int) TABLESPACE ts;
+  INSERT INTO t values(1);
+  DROP TABLE t;
+  eval DROP TABLESPACE ts ENGINE= $engine;
+  dec $i;
+}
+--enable_query_log
+

=== added file 'mysql-test/suite/falcon/t/falcon_bug_39708-master.opt'
--- a/mysql-test/suite/falcon/t/falcon_bug_39708-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_39708-master.opt	2008-10-29 11:41:14 +0000
@@ -0,0 +1 @@
+--falcon-page-size=2k

=== added file 'mysql-test/suite/falcon/t/falcon_bug_39708.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_39708.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_39708.test	2008-10-29 11:41:14 +0000
@@ -0,0 +1,5 @@
+--source include/have_falcon.inc
+
+--error ER_TOO_LONG_KEY
+CREATE TABLE t1(a VARCHAR(140) CHARACTER SET utf8, KEY(a)) ENGINE=falcon;
+SHOW WARNINGS;

=== added file 'mysql-test/suite/falcon/t/falcon_bug_40130.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_40130.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_40130.test	2008-11-05 15:04:45 +0000
@@ -0,0 +1,333 @@
+--source include/have_falcon.inc
+
+#
+# Bug #40130: Falcon date / time indexes broken
+#
+--echo *** Bug #40130 ***
+
+# ----------------------------------------------------- #
+# --- Initialisation                                --- #
+# ----------------------------------------------------- #
+let $engine = 'Falcon';
+eval SET @@storage_engine = $engine;
+
+--disable_warnings
+DROP TABLE IF EXISTS table10;
+--enable_warnings
+
+# ----------------------------------------------------- #
+# --- Test                                          --- #
+# ----------------------------------------------------- #
+
+CREATE TABLE table10 (`time_key` time, key (`time_key` ));
+INSERT INTO table10 VALUES ('23:43:55');
+INSERT INTO table10 VALUES ('03:18:59');
+INSERT INTO table10 VALUES ('05:05:23');
+INSERT INTO table10 VALUES ('09:20:40');
+INSERT INTO table10 VALUES ('22:32:50');
+INSERT INTO table10 VALUES ('07:41:31');
+INSERT INTO table10 VALUES ('10:52:13');
+INSERT INTO table10 VALUES ('12:40:54');
+INSERT INTO table10 VALUES ('10:33:25');
+INSERT INTO table10 VALUES ('22:11:46');
+
+SET AUTOCOMMIT=OFF;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '09:11:23' WHERE `time_key` < '16:23:56'; 
+INSERT INTO table10 VALUES ( '20:25:18' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '10:33:25' WHERE `time_key` > '22:11:46'; 
+INSERT INTO table10 VALUES ( '17:58:48' ); 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '00:16:10' ); 
+UPDATE table10 SET `time_key` = '16:05:35' WHERE `time_key` > '16:57:24'; 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '20:24:01' ); 
+INSERT INTO table10 VALUES ( '18:37:59' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '21:05:17' WHERE `time_key` < '06:07:07'; 
+INSERT INTO table10 VALUES ( '00:05:40' ); 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '13:34:36' ); 
+INSERT INTO table10 VALUES ( '22:35:15' ); 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '09:32:02' ); 
+INSERT INTO table10 VALUES ( '12:02:39' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '19:22:23' WHERE `time_key` < '03:39:55'; 
+UPDATE table10 SET `time_key` = '13:45:38' WHERE `time_key` < '03:52:41'; 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '21:57:00' WHERE `time_key` < '11:37:04'; 
+INSERT INTO table10 VALUES ( '18:56:03' ); 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '21:46:34' ); 
+INSERT INTO table10 VALUES ( '00:46:37' ); 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '11:54:45' ); 
+INSERT INTO table10 VALUES ( '11:00:16' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '04:41:27' WHERE `time_key` > '05:45:30'; 
+INSERT INTO table10 VALUES ( '05:55:02' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '02:51:17' WHERE `time_key` < '05:33:58'; 
+INSERT INTO table10 VALUES ( '06:07:14' ); 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '19:17:13' ); 
+UPDATE table10 SET `time_key` = '14:23:25' WHERE `time_key` < '18:44:25'; 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '01:54:06' ); 
+INSERT INTO table10 VALUES ( '05:36:42' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '04:04:15' WHERE `time_key` < '17:09:11'; 
+INSERT INTO table10 VALUES ( '13:22:58' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '03:45:01' WHERE `time_key` < '01:02:29'; 
+INSERT INTO table10 VALUES ( '14:45:34' ); 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '12:33:12' ); 
+INSERT INTO table10 VALUES ( '21:40:27' ); 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '05:05:45' ); 
+INSERT INTO table10 VALUES ( '01:21:15' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '01:43:44' WHERE `time_key` > '18:44:54'; 
+UPDATE table10 SET `time_key` = '16:00:25' WHERE `time_key` > '17:37:45'; 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '09:17:29' ); 
+UPDATE table10 SET `time_key` = '00:32:27' WHERE `time_key` < '19:55:22'; 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '00:01:27' WHERE `time_key` < '23:49:20'; 
+INSERT INTO table10 VALUES ( '11:10:06' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '21:52:14' WHERE `time_key` > '00:54:57'; 
+INSERT INTO table10 VALUES ( '10:32:20' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '05:48:51' WHERE `time_key` < '05:53:48'; 
+UPDATE table10 SET `time_key` = '04:11:47' WHERE `time_key` > '14:02:03'; 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '20:58:47' ); 
+INSERT INTO table10 VALUES ( '06:58:04' ); 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '14:41:45' ); 
+UPDATE table10 SET `time_key` = '00:45:47' WHERE `time_key` < '21:51:00'; 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '09:01:24' ); 
+INSERT INTO table10 VALUES ( '07:07:37' ); 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '06:25:00' ); 
+INSERT INTO table10 VALUES ( '05:47:01' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '12:31:51' WHERE `time_key` > '04:34:05'; 
+INSERT INTO table10 VALUES ( '01:31:26' ); 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '01:46:22' ); 
+INSERT INTO table10 VALUES ( '01:14:58' ); 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '04:09:31' ); 
+UPDATE table10 SET `time_key` = '08:28:13' WHERE `time_key` > '14:50:18'; 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '11:19:43' WHERE `time_key` < '04:30:14'; 
+INSERT INTO table10 VALUES ( '20:03:24' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '14:40:32' WHERE `time_key` < '15:30:08'; 
+UPDATE table10 SET `time_key` = '03:13:02' WHERE `time_key` < '21:47:42'; 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '20:37:56' ); 
+UPDATE table10 SET `time_key` = '15:51:19' WHERE `time_key` < '01:39:43'; 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '07:15:18' WHERE `time_key` > '05:37:40'; 
+INSERT INTO table10 VALUES ( '18:47:30' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '13:32:24' WHERE `time_key` > '23:38:12'; 
+INSERT INTO table10 VALUES ( '23:32:39' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '22:01:18' WHERE `time_key` < '17:51:48'; 
+INSERT INTO table10 VALUES ( '11:41:29' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '15:45:55' WHERE `time_key` > '04:03:52'; 
+UPDATE table10 SET `time_key` = '05:43:47' WHERE `time_key` < '07:29:01'; 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '23:44:48' WHERE `time_key` < '00:33:42'; 
+UPDATE table10 SET `time_key` = '08:56:04' WHERE `time_key` > '12:16:41'; 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '19:23:41' ); 
+INSERT INTO table10 VALUES ( '18:44:20' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '00:40:04' WHERE `time_key` > '11:34:06'; 
+UPDATE table10 SET `time_key` = '23:45:59' WHERE `time_key` < '09:44:50'; 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '18:54:59' WHERE `time_key` < '15:46:02'; 
+INSERT INTO table10 VALUES ( '17:37:41' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '17:08:04' WHERE `time_key` < '14:11:50'; 
+UPDATE table10 SET `time_key` = '21:33:59' WHERE `time_key` > '17:44:43'; 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '03:50:15' WHERE `time_key` > '19:35:18'; 
+UPDATE table10 SET `time_key` = '23:15:47' WHERE `time_key` < '12:18:46'; 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '22:50:01' ); 
+INSERT INTO table10 VALUES ( '17:29:53' ); 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '21:33:30' ); 
+INSERT INTO table10 VALUES ( '06:27:52' ); 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '07:49:31' ); 
+INSERT INTO table10 VALUES ( '21:31:25' );
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '13:50:22' ); 
+INSERT INTO table10 VALUES ( '15:13:07' ); 
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '14:06:24' ); 
+INSERT INTO table10 VALUES ( '19:10:11' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '05:03:39' WHERE `time_key` > '11:46:31'; 
+INSERT INTO table10 VALUES ( '04:35:34' );
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '14:37:01' WHERE `time_key` < '02:11:03'; 
+INSERT INTO table10 VALUES ( '10:52:22' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '15:37:40' WHERE `time_key` > '11:19:00'; 
+INSERT INTO table10 VALUES ( '08:46:29' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '07:59:59' WHERE `time_key` < '05:27:20'; 
+UPDATE table10 SET `time_key` = '00:45:15' WHERE `time_key` < '20:07:08';
+COMMIT;
+
+START TRANSACTION; 
+INSERT INTO table10 VALUES ( '00:51:31' ); 
+UPDATE table10 SET `time_key` = '10:00:58' WHERE `time_key` < '16:41:45'; 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '13:49:37' WHERE `time_key` > '10:40:48'; 
+INSERT INTO table10 VALUES ( '05:16:25' ); 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '14:46:15' WHERE `time_key` < '12:48:22'; 
+UPDATE table10 SET `time_key` = '05:50:46' WHERE `time_key` < '07:58:43'; 
+COMMIT;
+
+START TRANSACTION; 
+UPDATE table10 SET `time_key` = '00:11:06' WHERE `time_key` < '16:39:47'; 
+UPDATE table10 SET `time_key` = '04:13:41' WHERE `time_key` < '14:55:39'; 
+COMMIT;
+
+SELECT * FROM table10;
+
+START TRANSACTION;
+UPDATE table10 SET `time_key` = '00:28:04' WHERE `time_key` < '09:58:46'; 
+UPDATE table10 SET `time_key` = '04:56:25' WHERE `time_key` > '09:26:08'; 
+COMMIT;
+
+SELECT * FROM table10;
+
+# ----------------------------------------------------- #
+# --- Final cleanup                                 --- #
+# ----------------------------------------------------- #
+DROP TABLE table10;

=== added file 'mysql-test/suite/falcon/t/falcon_bug_40158.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_40158.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_40158.test	2008-11-05 14:51:37 +0000
@@ -0,0 +1,50 @@
+--source include/have_falcon.inc
+
+#
+# Bug #40158: Falcon assertion in StorageInterface::encodeRecord() line 2635 on CREATE TABLE
+#
+--echo *** Bug #40158 ***
+
+# ----------------------------------------------------- #
+# --- Initialisation                                --- #
+# ----------------------------------------------------- #
+let $engine = 'Falcon';
+eval SET @@storage_engine = $engine;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# ----------------------------------------------------- #
+# --- Test                                          --- #
+# ----------------------------------------------------- #
+
+CREATE TABLE t1 (`"strangename"` int);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
+SELECT `"strangename"` FROM t1;
+DROP TABLE t1;
+
+SET LOCAL SQL_MODE=ANSI_QUOTES;
+
+CREATE TABLE t1 ("""strangename""" int);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
+SELECT """strangename""" FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (`""strangename""` int);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
+SELECT `""strangename""` FROM t1;
+
+# ----------------------------------------------------- #
+# --- Check                                         --- #
+# ----------------------------------------------------- #
+
+SELECT COUNT(*) FROM t1;
+
+# ----------------------------------------------------- #
+# --- Final cleanup                                 --- #
+# ----------------------------------------------------- #
+DROP TABLE t1;

=== added file 'mysql-test/suite/rpl/r/rpl_backup.result'
--- a/mysql-test/suite/rpl/r/rpl_backup.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_backup.result	2008-11-17 09:57:51 +0000
@@ -0,0 +1,335 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+Create some data...
+CREATE DATABASE rpl_backup;
+CREATE TABLE rpl_backup.t1 (a int);
+INSERT INTO rpl_backup.t1 VALUES (1), (2), (3), (4), (5);
+Remove all entries in the backup logs.
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+Remove all entries in the backup logs.
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+Get master's binlog position from the slave before backup.
+Get master's binlog position before backup.
+SET SESSION debug="+d,set_backup_id";
+Backup_id = 500.
+BACKUP DATABASE rpl_backup TO 'rpl_bup_m1.bak';
+backup_id
+500
+SET SESSION debug="-d";
+Show any events issued as a result of backup.
+Note: There should be none!
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+Verify backup run on master does not advance binlog pos.
+Get master's binlog position after backup.
+Compare the before position of the master's binlog to
+the after position of the master's binlog. The result
+should be 0.
+Delta
+0
+Should have count(*) = 0.
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+0
+Verify backup run on master does not advance binlog pos.
+Get master's binlog position on the slave after backup.
+Compare the before position of the master's binlog to
+the after position of the slave's binlog as shown on
+on the slave. The result should be 0.
+Delta
+0
+SHOW SLAVE STATUS;
+Slave_IO_State	#
+Master_Host	127.0.0.1
+Master_User	root
+Master_Port	MASTER_PORT
+Connect_Retry	1
+Master_Log_File	#
+Read_Master_Log_Pos	#
+Relay_Log_File	#
+Relay_Log_Pos	#
+Relay_Master_Log_File	master-bin.000001
+Slave_IO_Running	Yes
+Slave_SQL_Running	Yes
+Replicate_Do_DB	
+Replicate_Ignore_DB	
+Replicate_Do_Table	
+Replicate_Ignore_Table	
+Replicate_Wild_Do_Table	
+Replicate_Wild_Ignore_Table	
+Last_Errno	0
+Last_Error	
+Skip_Counter	0
+Exec_Master_Log_Pos	#
+Relay_Log_Space	#
+Until_Condition	None
+Until_Log_File	
+Until_Log_Pos	0
+Master_SSL_Allowed	No
+Master_SSL_CA_File	
+Master_SSL_CA_Path	
+Master_SSL_Cert	
+Master_SSL_Cipher	
+Master_SSL_Key	
+Seconds_Behind_Master	#
+Master_SSL_Verify_Server_Cert	No
+Last_IO_Errno	0
+Last_IO_Error	
+Last_SQL_Errno	0
+Last_SQL_Error	
+Ensure replication is still working...
+Cleanup from last error on master and slave.
+DELETE FROM rpl_backup.t1;
+INSERT INTO rpl_backup.t1 VALUES (11), (22), (33);
+SELECT count(*) FROM rpl_backup.t1;
+count(*)
+3
+SELECT count(*) FROM rpl_backup.t1;
+count(*)
+3
+Cleanup backup logs.
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+First, get master's binlog position and filename.
+SET SESSION debug="+d,set_backup_id";
+Backup_id = 600.
+BACKUP DATABASE rpl_backup TO 'rpl_bup_s1.bak';
+backup_id
+600
+SET SESSION debug="-d";
+SHOW SLAVE STATUS;
+Slave_IO_State	#
+Master_Host	127.0.0.1
+Master_User	root
+Master_Port	MASTER_PORT
+Connect_Retry	1
+Master_Log_File	#
+Read_Master_Log_Pos	#
+Relay_Log_File	#
+Relay_Log_Pos	#
+Relay_Master_Log_File	master-bin.000001
+Slave_IO_Running	Yes
+Slave_SQL_Running	Yes
+Replicate_Do_DB	
+Replicate_Ignore_DB	
+Replicate_Do_Table	
+Replicate_Ignore_Table	
+Replicate_Wild_Do_Table	
+Replicate_Wild_Ignore_Table	
+Last_Errno	0
+Last_Error	
+Skip_Counter	0
+Exec_Master_Log_Pos	#
+Relay_Log_Space	#
+Until_Condition	None
+Until_Log_File	
+Until_Log_Pos	0
+Master_SSL_Allowed	No
+Master_SSL_CA_File	
+Master_SSL_CA_Path	
+Master_SSL_Cert	
+Master_SSL_Cipher	
+Master_SSL_Key	
+Seconds_Behind_Master	#
+Master_SSL_Verify_Server_Cert	No
+Last_IO_Errno	0
+Last_IO_Error	
+Last_SQL_Errno	0
+Last_SQL_Error	
+Check saving of master's binlog information.
+Should have count(*) = 1.
+count(*)
+1
+Should have count(*) = 1.
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+1
+INSERT INTO rpl_backup.t1 VALUES (10), (20), (30);
+Backup_id = 501.
+BACKUP DATABASE rpl_backup TO 'rpl_bup_m2.bak';
+backup_id
+501
+SELECT count(*) FROM rpl_backup.t1;
+count(*)
+6
+SELECT count(*) FROM rpl_backup.t1;
+count(*)
+6
+Make a backup for later use.
+Backup_id = 601.
+BACKUP DATABASE rpl_backup TO 'rpl_bup_s2.bak';
+backup_id
+601
+CREATE TABLE rpl_backup.t2 (b int);
+INSERT INTO rpl_backup.t2 VALUES (888), (999);
+Get master's binlog position before restore.
+Backup_id = 502.
+RESTORE FROM 'rpl_bup_m2.bak' OVERWRITE;
+backup_id
+502
+Show the incident event issued as a result of restore.
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Incident	1	#	#2 (RESTORE_ON_MASTER)
+master-bin.000001	#	Rotate	1	#	master-bin.000002;pos=4
+Showing tables on master.
+SHOW FULL TABLES FROM rpl_backup;
+Tables_in_rpl_backup	Table_type
+t1	BASE TABLE
+SELECT count(*) FROM rpl_backup.t1;
+count(*)
+6
+Check slave got everything up to incident event.
+Should be two rows: 888, 999.
+SELECT * FROM rpl_backup.t2 WHERE b > 800;
+b
+888
+999
+SHOW SLAVE STATUS;
+Slave_IO_State	#
+Master_Host	127.0.0.1
+Master_User	root
+Master_Port	MASTER_PORT
+Connect_Retry	1
+Master_Log_File	#
+Read_Master_Log_Pos	#
+Relay_Log_File	#
+Relay_Log_Pos	#
+Relay_Master_Log_File	master-bin.000001
+Slave_IO_Running	Yes
+Slave_SQL_Running	No
+Replicate_Do_DB	
+Replicate_Ignore_DB	
+Replicate_Do_Table	
+Replicate_Ignore_Table	
+Replicate_Wild_Do_Table	
+Replicate_Wild_Ignore_Table	
+Last_Errno	1590
+Last_Error	The incident RESTORE_ON_MASTER occured on the master. Message: A restore operation was initiated on the master.
+Skip_Counter	0
+Exec_Master_Log_Pos	#
+Relay_Log_Space	#
+Until_Condition	None
+Until_Log_File	
+Until_Log_Pos	0
+Master_SSL_Allowed	No
+Master_SSL_CA_File	
+Master_SSL_CA_Path	
+Master_SSL_Cert	
+Master_SSL_Cipher	
+Master_SSL_Key	
+Seconds_Behind_Master	#
+Master_SSL_Verify_Server_Cert	No
+Last_IO_Errno	0
+Last_IO_Error	
+Last_SQL_Errno	1590
+Last_SQL_Error	The incident RESTORE_ON_MASTER occured on the master. Message: A restore operation was initiated on the master.
+Show the slave stopped with an error.
+Last_SQL_Error
+The incident RESTORE_ON_MASTER occured on the master. Message: A restore operation was initiated on the master.
+SET global sql_slave_skip_counter=1;
+STOP SLAVE;
+START SLAVE;
+Showing tables on slave.
+SHOW FULL TABLES FROM rpl_backup;
+Tables_in_rpl_backup	Table_type
+t1	BASE TABLE
+t2	BASE TABLE
+STOP SLAVE;
+Backup_id = 602.
+RESTORE FROM '../master-data/rpl_bup_m2.bak' OVERWRITE;
+backup_id
+602
+Showing databases on slave.
+SHOW DATABASES LIKE 'rpl_backup%';
+Database (rpl_backup%)
+rpl_backup
+SELECT count(*) FROM rpl_backup.t1;
+count(*)
+6
+START SLAVE;
+Make a backup for later use.
+Backup_id = 603.
+BACKUP DATABASE rpl_backup TO 'rpl_bup_s3.bak';
+backup_id
+603
+Test restore on slave while replication turned on.
+RESTORE FROM 'rpl_bup_s1.bak' OVERWRITE;
+ERROR HY000: A restore operation was attempted on a slave during replication. You must stop the slave prior to running a restore.
+Stop slave and restart after restore.
+STOP SLAVE;
+RESTORE FROM 'rpl_bup_s3.bak' OVERWRITE;
+backup_id
+#
+START SLAVE;
+Checking affect on replication.
+INSERT INTO rpl_backup.t1 VALUES (44), (55), (66);
+SELECT * FROM rpl_backup.t1 ORDER BY a;
+a
+10
+11
+20
+22
+30
+33
+44
+55
+66
+SELECT * FROM rpl_backup.t1 ORDER BY a;
+a
+10
+11
+20
+22
+30
+33
+44
+55
+66
+Stop replication and turn off binary log.
+STOP SLAVE;
+SET @orig_sql_log_bin= @@sql_log_bin;
+Turn off binlog.
+SET @@sql_log_bin= 0;
+SHOW VARIABLES LIKE '%log_bin';
+Variable_name	Value
+log_bin	ON
+sql_log_bin	OFF
+Backup_id = 503.
+BACKUP DATABASE rpl_backup TO 'rpl_bup_m3.bak';
+backup_id
+503
+Turn on binlog;
+SET @@sql_log_bin= @orig_sql_log_bin;
+SHOW VARIABLES LIKE '%log_bin';
+Variable_name	Value
+log_bin	ON
+sql_log_bin	ON
+RESET MASTER;
+Get master's binlog position before restore.
+Backup_id = 504.
+RESTORE FROM 'rpl_bup_m3.bak' OVERWRITE;
+backup_id
+504
+Get master's binlog position after restore.
+Show the incident event issued as a result of restore.
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Incident	1	#	#2 (RESTORE_ON_MASTER)
+master-bin.000001	#	Rotate	1	#	master-bin.000002;pos=4
+Compute the difference of the binlog positions.
+Result should be 0.
+Compare the before position of the master's binlog to
+the after position of the master's binlog. The result
+should be 0.
+Delta
+0
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+DROP DATABASE rpl_backup;
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+DROP DATABASE rpl_backup;

=== added file 'mysql-test/suite/rpl/t/rpl_backup.test'
--- a/mysql-test/suite/rpl/t/rpl_backup.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_backup.test	2008-11-17 09:57:51 +0000
@@ -0,0 +1,399 @@
+#
+# Test backup and replication integration.
+#
+
+--source include/master-slave.inc
+--source include/not_embedded.inc
+--source include/have_debug_sync.inc
+--source include/have_debug.inc
+
+connection master;
+
+--echo Create some data...
+CREATE DATABASE rpl_backup;
+CREATE TABLE rpl_backup.t1 (a int);
+INSERT INTO rpl_backup.t1 VALUES (1), (2), (3), (4), (5);
+
+#
+# Use Case 1 - Backup performed on a master.
+#   When a backup is performed on a master, the master shall not log 
+#   the backup event nor shall the master replicate any data produced
+#   (logged) by the backup. 
+
+--echo Remove all entries in the backup logs.
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+
+sync_slave_with_master;
+connection slave;
+
+--echo Remove all entries in the backup logs.
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+
+--echo Get master's binlog position from the slave before backup.
+let $slave_before_pos = 
+  query_get_value("SHOW SLAVE STATUS", Read_Master_Log_Pos, 1);
+
+connection master;
+
+--echo Get master's binlog position before backup.
+let $master_before_pos = query_get_value("SHOW MASTER STATUS", Position, 1);
+
+#
+# Now test read of backupid with known id using debug insertion
+#
+SET SESSION debug="+d,set_backup_id";
+
+# We are using debug insertion to set the first backup_id to
+# 500 so we can expect the output of this operation to be 500.
+--echo Backup_id = 500.
+BACKUP DATABASE rpl_backup TO 'rpl_bup_m1.bak';
+
+SET SESSION debug="-d";
+
+--echo Show any events issued as a result of backup.
+--echo Note: There should be none!
+--disable_query_log
+eval SHOW BINLOG EVENTS FROM $master_before_pos;
+--enable_query_log
+
+--echo Verify backup run on master does not advance binlog pos.
+--echo Get master's binlog position after backup.
+let $master_after_pos = query_get_value("SHOW MASTER STATUS", Position, 1);
+
+--disable_query_log
+--echo Compare the before position of the master's binlog to
+--echo the after position of the master's binlog. The result
+--echo should be 0.
+eval SELECT $master_after_pos - $master_before_pos AS Delta;
+--enable_query_log
+
+#
+# Now check slave to see if backup logs are affected.
+# Check slave's master position.
+# Ensure replication is still working.
+#
+sync_slave_with_master;
+connection slave;
+
+#
+# This tests is added to ensure none of the entries in the master's
+# backup logs are replicated to the slave.
+#
+--echo Should have count(*) = 0.
+SELECT count(*) FROM mysql.backup_history;
+
+--echo Verify backup run on master does not advance binlog pos.
+--echo Get master's binlog position on the slave after backup.
+let $slave_after_pos = 
+  query_get_value("SHOW SLAVE STATUS", Read_Master_Log_Pos, 1);
+
+--disable_query_log
+--echo Compare the before position of the master's binlog to
+--echo the after position of the slave's binlog as shown on
+--echo on the slave. The result should be 0.
+eval SELECT $slave_after_pos - $slave_before_pos AS Delta;
+--enable_query_log
+
+--replace_result $MASTER_MYPORT MASTER_PORT
+--replace_column 1 # 6 # 7 # 8 # 9 # 22 # 23 # 33 #
+--query_vertical SHOW SLAVE STATUS
+
+connection master;
+
+--echo Ensure replication is still working...
+--echo Cleanup from last error on master and slave.
+
+DELETE FROM rpl_backup.t1;
+
+INSERT INTO rpl_backup.t1 VALUES (11), (22), (33);
+
+SELECT count(*) FROM rpl_backup.t1;
+
+sync_slave_with_master;
+connection slave;
+
+SELECT count(*) FROM rpl_backup.t1;
+
+--echo Cleanup backup logs.
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+
+#
+#  Use Case 3 - Backup performed on a slave (part 1 of 2)
+#    Test backup on slave where slave has no slaves.
+#    Also, verify master's binlog information is saved to
+#      the progress log.
+#
+
+connection master;
+
+--echo First, get master's binlog position and filename.
+let $master_pos = query_get_value("SHOW MASTER STATUS", Position, 1);
+let $master_file = query_get_value("SHOW MASTER STATUS", File, 1);
+
+connection slave;
+
+#
+# Now test read of backupid with known id using debug insertion
+#
+
+SET SESSION debug="+d,set_backup_id";
+
+# We are using debug insertion to set the first backup_id to
+# 600 so we can expect the output of this operation to be 600.
+--echo Backup_id = 600.
+BACKUP DATABASE rpl_backup TO 'rpl_bup_s1.bak';
+
+SET SESSION debug="-d";
+
+--replace_result $MASTER_MYPORT MASTER_PORT
+--replace_column 1 # 6 # 7 # 8 # 9 # 22 # 23 # 33 #
+--query_vertical SHOW SLAVE STATUS
+
+#
+# Build search string for known master binlog information.
+#
+let $preamble = 'Recording master binlog information. binlog file = ''';
+let $middle = ''', position = ';
+let $end = '.';
+
+--echo Check saving of master's binlog information.
+--echo Should have count(*) = 1.
+--disable_query_log
+eval SELECT count(*) FROM mysql.backup_progress 
+WHERE Backup_id = 600 AND 
+notes = concat($preamble, "$master_file", $middle, $master_pos, $end);
+--enable_query_log
+
+--echo Should have count(*) = 1.
+SELECT count(*) FROM mysql.backup_history;
+
+connection master;
+
+#
+# Run backups for later use.
+#
+
+INSERT INTO rpl_backup.t1 VALUES (10), (20), (30);
+
+--echo Backup_id = 501.
+BACKUP DATABASE rpl_backup TO 'rpl_bup_m2.bak';
+
+SELECT count(*) FROM rpl_backup.t1;
+
+sync_slave_with_master;
+connection slave;
+
+SELECT count(*) FROM rpl_backup.t1;
+
+--echo Make a backup for later use.
+--echo Backup_id = 601.
+BACKUP DATABASE rpl_backup TO 'rpl_bup_s2.bak';
+
+#
+#  Use Case 2 - Restore performed on a master.
+#
+
+connection master;
+
+#
+# Insert some data to check slave with later.
+#
+
+CREATE TABLE rpl_backup.t2 (b int);
+INSERT INTO rpl_backup.t2 VALUES (888), (999);
+
+--echo Get master's binlog position before restore.
+let $master_before_pos = query_get_value("SHOW MASTER STATUS", Position, 1);
+
+--echo Backup_id = 502.
+RESTORE FROM 'rpl_bup_m2.bak' OVERWRITE;
+
+--echo Show the incident event issued as a result of restore.
+--replace_column 2 # 5 #
+--disable_query_log
+eval SHOW BINLOG EVENTS FROM $master_before_pos;
+--enable_query_log
+
+--echo Showing tables on master.
+SHOW FULL TABLES FROM rpl_backup;
+
+SELECT count(*) FROM rpl_backup.t1;
+
+#
+# Wait for slave to stop as result of incident event.
+#
+source include/wait_for_slave_sql_to_stop.inc;
+
+connection slave;
+
+--echo Check slave got everything up to incident event.
+--echo Should be two rows: 888, 999.
+SELECT * FROM rpl_backup.t2 WHERE b > 800;
+
+--replace_result $MASTER_MYPORT MASTER_PORT
+--replace_column 1 # 6 # 7 # 8 # 9 # 22 # 23 # 33 #
+--query_vertical SHOW SLAVE STATUS
+
+--echo Show the slave stopped with an error.
+LET $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
+disable_query_log;
+eval SELECT "$last_error" AS Last_SQL_Error;
+enable_query_log;
+
+SET global sql_slave_skip_counter=1;
+
+STOP SLAVE;
+--source include/wait_for_slave_to_stop.inc
+
+START SLAVE;
+--source include/wait_for_slave_to_start.inc
+
+# Sync with master to ensure nothing is replicated after incident event.
+sync_with_master;
+
+--echo Showing tables on slave.
+SHOW FULL TABLES FROM rpl_backup;
+
+#
+# Cleanup replication for next test case.
+#
+
+# Now stop the slave, do the restore, then restart.
+STOP SLAVE;
+--source include/wait_for_slave_to_stop.inc
+
+--echo Backup_id = 602.
+RESTORE FROM '../master-data/rpl_bup_m2.bak' OVERWRITE;
+
+--echo Showing databases on slave.
+SHOW DATABASES LIKE 'rpl_backup%';
+
+SELECT count(*) FROM rpl_backup.t1;
+
+START SLAVE;
+--source include/wait_for_slave_to_start.inc
+
+--echo Make a backup for later use.
+--echo Backup_id = 603.
+BACKUP DATABASE rpl_backup TO 'rpl_bup_s3.bak';
+
+#
+#  Use Case 4 - Restore performed on a slave.
+#
+
+connection slave;
+
+--echo Test restore on slave while replication turned on.
+
+--error ER_RESTORE_ON_SLAVE
+RESTORE FROM 'rpl_bup_s1.bak' OVERWRITE;
+
+--echo Stop slave and restart after restore.
+STOP SLAVE;
+
+--replace_column 1 #
+RESTORE FROM 'rpl_bup_s3.bak' OVERWRITE;
+
+START SLAVE;
+--source include/wait_for_slave_to_start.inc
+
+connection master;
+
+--echo Checking affect on replication.
+INSERT INTO rpl_backup.t1 VALUES (44), (55), (66);
+SELECT * FROM rpl_backup.t1 ORDER BY a;
+
+sync_slave_with_master;
+connection slave;
+SELECT * FROM rpl_backup.t1 ORDER BY a;
+
+#
+#  Use Case 3 - Backup performed on a slave (part 2 of 2)
+#    Test backup on slave with another slave attached.
+#
+#  Note: To be added as part of WL#4612
+
+#
+#  Use Case 5 - Backup run with no binary log.
+#
+#  Note: This is basically covered in Use Case 2 but the distinction is 
+#        we have explicitly turned off binary logging. 
+#
+
+--echo Stop replication and turn off binary log.
+connection slave;
+
+STOP SLAVE;
+--source include/wait_for_slave_to_stop.inc
+
+connection master;
+
+SET @orig_sql_log_bin= @@sql_log_bin;
+
+--echo Turn off binlog.
+SET @@sql_log_bin= 0;
+SHOW VARIABLES LIKE '%log_bin';
+
+--echo Backup_id = 503.
+BACKUP DATABASE rpl_backup TO 'rpl_bup_m3.bak';
+
+--echo Turn on binlog;
+SET @@sql_log_bin= @orig_sql_log_bin;
+SHOW VARIABLES LIKE '%log_bin';
+
+#
+#  Use Case 6 - Restore run with binary log turned on but no slaves attached.
+#  
+
+RESET MASTER;
+
+--echo Get master's binlog position before restore.
+let $master_before_pos = query_get_value("SHOW MASTER STATUS", Position, 1);
+
+--echo Backup_id = 504.
+RESTORE FROM 'rpl_bup_m3.bak' OVERWRITE;
+
+--echo Get master's binlog position after restore.
+let $master_after_pos = query_get_value("SHOW MASTER STATUS", Position, 1);
+
+--echo Show the incident event issued as a result of restore.
+--replace_column 2 # 5 #
+--disable_query_log
+eval SHOW BINLOG EVENTS FROM $master_before_pos;
+--enable_query_log
+
+--echo Compute the difference of the binlog positions.
+--echo Result should be 0.
+--disable_query_log
+--echo Compare the before position of the master's binlog to
+--echo the after position of the master's binlog. The result
+--echo should be 0.
+eval SELECT $master_after_pos - $master_before_pos AS Delta;
+--enable_query_log
+
+#
+# Cleanup
+#
+connection master;
+
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+DROP DATABASE rpl_backup;
+
+--remove_file $MYSQLTEST_VARDIR/master-data/rpl_bup_m1.bak
+--remove_file $MYSQLTEST_VARDIR/master-data/rpl_bup_m2.bak
+--remove_file $MYSQLTEST_VARDIR/master-data/rpl_bup_m3.bak
+
+connection slave;
+
+FLUSH BACKUP LOGS;
+PURGE BACKUP LOGS;
+DROP DATABASE rpl_backup;
+
+--remove_file $MYSQLTEST_VARDIR/slave-data/rpl_bup_s1.bak
+--remove_file $MYSQLTEST_VARDIR/slave-data/rpl_bup_s2.bak
+--remove_file $MYSQLTEST_VARDIR/slave-data/rpl_bup_s3.bak
+

=== added file 'mysql-test/suite/sys_vars/t/disabled.def'
--- a/mysql-test/suite/sys_vars/t/disabled.def	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/disabled.def	2008-11-26 15:16:58 +0000
@@ -0,0 +1,21 @@
+##############################################################################
+#
+#  List the test cases that are to be disabled temporarily.
+#
+#  Separate the test case name and the comment with ':'.
+#
+#    <testcasename> : BUG#<xxxx> <date disabled> <disabler> <comment>
+#
+#  Do not use any TAB characters for whitespace.
+#
+##############################################################################
+key_buffer_size_basic_64    : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+rpl_recovery_rank_basic_64  : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+sort_buffer_size_basic_64   : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+query_cache_size_basic_32   : Bug#36747: Allocating a large query cache is not deterministic
+query_cache_size_basic_64   : Bug#36747: Allocating a large query cache is not deterministic
+query_alloc_block_size_basic_64:  Bug #37708 query_alloc_block_size_basic_64 fails in pushbuild
+sort_buffer_size_basic_32   : Bug#36875 main.sort_buffer_size_basic_32 fails on some systems
+key_buffer_size_basic_32    : Bug#36876 main.key_buffer_size_basic_32 fails on some systems
+max_heap_table_size_basic_32 : Bug#36877 main.max_heap_table_size_basic_32 fails on some systems
+tmp_table_size_basic_32     : Bug#36878 main.tmp_table_size_basic_32 fails on some systems

=== modified file 'mysql-test/t/disabled.def'
--- a/mysql-test/t/disabled.def	2008-11-07 11:45:16 +0000
+++ b/mysql-test/t/disabled.def	2008-11-26 15:16:58 +0000
@@ -9,32 +9,14 @@
 #  Do not use any TAB characters for whitespace.
 #
 ##############################################################################
-innodb          : WL#1213: Waiting for InnoDB team to add support for 4-byte character sets.
-concurrent_innodb        : BUG#21579 2006-08-11 mleich innodb_concurrent random failures with varying differences
 federated_transactions   : Bug#29523 Transactions do not work
 show_check      : Bug #32682    Test show_check fails in 6.0
 lowercase_table3         : Bug#32667 lowercase_table3.test reports to error log
-rpl_log_pos          : Bug#8693 Test 'rpl_log_pos' fails sometimes
 ctype_create         : Bug#32965 main.ctype_create fails
-backup_no_engine     : Bug#36021 2008-04-13 rsomla server crashes when openning table with unknown storage engine
 csv_alter_table      : Bug#33696 2008-01-21 pcrews no .result file - bug allows NULL columns in CSV tables
-query_cache_wlock_invalidate_func: Bug#35390 causes not deterministic results.
 cast                 : Bug#35594 2008-03-27 main.cast fails on Windows2003-64
-maria-preload        : Bug#35107 crashes
-key_buffer_size_basic_64    : Bug #36522: Some tests of system variables have diffs on 64bit platorms
-rpl_recovery_rank_basic_64  : Bug #36522: Some tests of system variables have diffs on 64bit platorms
-sort_buffer_size_basic_64   : Bug #36522: Some tests of system variables have diffs on 64bit platorms
-log_output_basic      : Bug#34820 log_output can be set to illegal value
-query_cache_size_basic_32   : Bug#36747: Allocating a large query cache is not deterministic
-query_cache_size_basic_64   : Bug#36747: Allocating a large query cache is not deterministic
-query_alloc_block_size_basic_64:  Bug #37708 query_alloc_block_size_basic_64 fails in pushbuild
 wait_timeout_func           : Bug #36873 wait_timeout_func.test fails randomly
 timestamp_func              : Bug #37702 timestamp_func relies on sleep and is unstable in pushbuild
-sort_buffer_size_basic_32   : Bug#36875 main.sort_buffer_size_basic_32 fails on some systems
-key_buffer_size_basic_32    : Bug#36876 main.key_buffer_size_basic_32 fails on some systems
-max_heap_table_size_basic_32 : Bug#36877 main.max_heap_table_size_basic_32 fails on some systems
-tmp_table_size_basic_32     : Bug#36878 main.tmp_table_size_basic_32 fails on some systems
-backup_triggers_and_events  : Bug#37762 2008-07-01 rafal Test fails on remove_file for unknown reasons
-backup_no_be                : Bug#38023 2008-07-16 rafal Test triggers valgrind warnings described in the bug
-user_limits                 : Bug#23921 2008-07-25 joro random failure of user_limits.test
 thread_cache_size_func      : Bug#40574 2008-11-07 joro main.thread_cache_size_func fails in pushbuild when run with pool of threads
+log_output_basic     : Bug #40988       log_output_basic.test succeeded though syntactically false.
+innodb               : Bug #41056    Innodb.test shows some difference to its result file.

=== modified file 'mysql-test/t/implicit_commit.test'
--- a/mysql-test/t/implicit_commit.test	2008-07-27 13:14:46 +0000
+++ b/mysql-test/t/implicit_commit.test	2008-11-20 14:03:27 +0000
@@ -1136,7 +1136,7 @@ source include/implicit_commit_helper.in
 --echo #
 
 let $statement=
-  restore from 'backup_db1.ba';
+  restore from 'backup_db1.ba' overwrite;
 source include/implicit_commit_helper.inc;
 
 --remove_file $MYSQLTEST_VARDIR/master-data/backup_db1.ba

=== modified file 'sql/backup/backup_info.cc'
--- a/sql/backup/backup_info.cc	2008-11-25 16:37:46 +0000
+++ b/sql/backup/backup_info.cc	2008-12-04 23:14:30 +0000
@@ -543,6 +543,10 @@ int Backup_info::add_dbs(THD *thd, List<
   while ((s= it++))
   {
     backup::String db_name(*s);
+
+    // Ignore the database if it has already been inserted into the catalogue.    
+    if (has_db(db_name))
+      continue;
     
     if (is_internal_db_name(&db_name))
     {

=== modified file 'sql/backup/backup_info.h'
--- a/sql/backup/backup_info.h	2008-11-19 16:32:01 +0000
+++ b/sql/backup/backup_info.h	2008-12-04 23:14:30 +0000
@@ -48,6 +48,10 @@ class Backup_info: public backup::Image_
 
  private:
 
+  // Prevent copying/assignments
+  Backup_info(const Backup_info&);
+  Backup_info& operator=(const Backup_info&);
+
   class Global_iterator; ///< Iterates over global items (for which meta-data is stored).
   class Perdb_iterator;  ///< Iterates over all per-database objects (except tables).
 

=== modified file 'sql/backup/backup_kernel.h'
--- a/sql/backup/backup_kernel.h	2008-10-27 13:06:21 +0000
+++ b/sql/backup/backup_kernel.h	2008-11-17 09:57:51 +0000
@@ -30,7 +30,7 @@ void backup_shutdown();
   Called from the big switch in mysql_execute_command() to execute
   backup related statement
 */
-int execute_backup_command(THD*, LEX*, String*);
+int execute_backup_command(THD*, LEX*, String*, bool);
 
 // forward declarations
 
@@ -74,7 +74,7 @@ class Backup_restore_ctx: public backup:
                                    const char*);  
 
   int do_backup();
-  int do_restore();
+  int do_restore(bool overwrite);
   int fatal_error(int, ...);
   int log_error(int, ...);
 
@@ -84,6 +84,10 @@ class Backup_restore_ctx: public backup:
 
  private:
 
+  // Prevent copying/assignments
+  Backup_restore_ctx(const Backup_restore_ctx&);
+  Backup_restore_ctx& operator=(const Backup_restore_ctx&);
+
   /** @c current_op points to the @c Backup_restore_ctx for the
       ongoing backup/restore operation.  If pointer is null, no
       operation is currently running. */
@@ -133,6 +137,12 @@ class Backup_restore_ctx: public backup:
     Indicates if tables have been locked with @c lock_tables_for_restore()
   */
   bool m_tables_locked; 
+
+  /**
+    Indicates we must turn binlog back on in the close method. This is
+    set to TRUE in the prepare_for_restore() method.
+  */
+  bool m_engage_binlog;
 
   int lock_tables_for_restore();
   void unlock_tables();

=== modified file 'sql/backup/be_snapshot.cc'
--- a/sql/backup/be_snapshot.cc	2008-08-08 19:58:37 +0000
+++ b/sql/backup/be_snapshot.cc	2008-10-30 12:29:54 +0000
@@ -126,7 +126,15 @@ result_t Backup::get_data(Buffer &buf)
     // open_and_lock_tables. Otherwise, open_and_lock_tables will try to open
     // previously opened views and crash.
     locking_thd->m_thd->lex->cleanup_after_one_table_open();
-    open_and_lock_tables(locking_thd->m_thd, locking_thd->tables_in_backup);
+    /*
+      The MYSQL_OPEN_SKIP_TEMPORARY flag is needed so that temporary tables are
+      not opened which would occulde the regular tables selected for backup 
+      (BUG#33574).
+     */ 
+    open_and_lock_tables_derived(locking_thd->m_thd, 
+                                 locking_thd->tables_in_backup,
+                                 FALSE, /* do not process derived tables */
+                                 MYSQL_OPEN_SKIP_TEMPORARY);
     tables_open= TRUE;
   }
   if (locking_thd->lock_state == LOCK_ACQUIRED)

=== modified file 'sql/backup/be_thread.cc'
--- a/sql/backup/be_thread.cc	2008-07-09 07:12:43 +0000
+++ b/sql/backup/be_thread.cc	2008-10-30 12:29:54 +0000
@@ -161,7 +161,16 @@ pthread_handler_t backup_thread_for_lock
     killing the thread. In this case, we need to close the tables 
     and exit.
   */
-  if (open_and_lock_tables(thd, locking_thd->tables_in_backup))
+
+  /*
+    The MYSQL_OPEN_SKIP_TEMPORARY flag is needed so that temporary tables are
+    not opened which would occulde the regular tables selected for backup 
+    (BUG#33574).
+  */ 
+  if (open_and_lock_tables_derived(thd, locking_thd->tables_in_backup,
+                                   FALSE, /* do not process derived tables */
+                                   MYSQL_OPEN_SKIP_TEMPORARY)
+     )
   {
     DBUG_PRINT("info",("Online backup locking thread dying"));
     THD_SET_PROC_INFO(thd, "lock error");

=== modified file 'sql/backup/data_backup.cc'
--- a/sql/backup/data_backup.cc	2008-10-14 12:08:56 +0000
+++ b/sql/backup/data_backup.cc	2008-10-30 20:02:15 +0000
@@ -552,6 +552,25 @@ int write_table_data(THD* thd, Backup_in
     DBUG_PRINT("backup_data",("-- PREPARE PHASE --"));
     DEBUG_SYNC(thd, "before_backup_data_prepare");
 
+    /*
+      Note: block_commits is performed here because of the global read
+      lock/table lock deadlock reported in bug#39602. It should be
+      moved back to right before sch.lock() once a refined commit
+      blocker has been implemented. WL#4610 tracks the work on a
+      refined commit blocker
+    */
+    /*
+      Block commits.
+
+      TODO: Step 2 of the commit blocker has been skipped for this release.
+      When it is included, developer needs to build a list of all of the
+      non-transactional tables and pass that to block_commits().
+    */
+    int error= 0;
+    error= block_commits(thd, NULL);
+    if (error)
+      goto error;
+
     if (sch.prepare())
       goto error;
 
@@ -574,16 +593,8 @@ int write_table_data(THD* thd, Backup_in
     DEBUG_SYNC(thd, "after_backup_validated");
     
     /*
-      Block commits.
-
-      TODO: Step 2 of the commit blocker has been skipped for this release.
-      When it is included, developer needs to build a list of all of the
-      non-transactional tables and pass that to block_commits().
+      Refined commit blocker should be set here; see WL#4610
     */
-    int error= 0;
-    error= block_commits(thd, NULL);
-    if (error)
-      goto error;
 
     DEBUG_SYNC(thd, "before_backup_data_lock");
     if (sch.lock())
@@ -600,6 +611,19 @@ int write_table_data(THD* thd, Backup_in
       }
 
     /*
+      If we are a connected slave, write master's binlog information to
+      the progress log for later use.
+    */
+    st_bstream_binlog_pos master_pos;
+    master_pos.pos= 0;
+    master_pos.file= 0;
+    if (obs::is_slave() && active_mi)
+    {
+      master_pos.pos= (ulong)active_mi->master_log_pos;
+      master_pos.file= active_mi->master_log_name;
+    }
+
+    /*
       Save VP creation time.
     */
     vp_time= my_time(0);
@@ -626,6 +650,13 @@ int write_table_data(THD* thd, Backup_in
       info.save_binlog_pos(binlog_pos);
       info.m_ctx.report_binlog_pos(info.binlog_pos);
     }
+
+    /*
+      If we are a slave and the master's binlog position has been recorded
+      write it to the log.
+    */
+    if (obs::is_slave() && master_pos.pos)
+      info.m_ctx.report_master_binlog_pos(master_pos);
 
     info.m_ctx.report_state(BUP_RUNNING);
     DEBUG_SYNC(thd, "after_backup_binlog");

=== modified file 'sql/backup/image_info.cc'
--- a/sql/backup/image_info.cc	2008-10-14 12:08:56 +0000
+++ b/sql/backup/image_info.cc	2008-11-05 09:41:15 +0000
@@ -206,7 +206,7 @@ int Image_info::add_snapshot(Snapshot_in
 /**
   Check if catalogue contains given database.
  */ 
-bool Image_info::has_db(const String &db_name)
+bool Image_info::has_db(const String &db_name) const
 {
   for (uint n=0; n < m_dbs.count() ; ++n)
     if (m_dbs[n] && m_dbs[n]->name() == db_name)

=== modified file 'sql/backup/image_info.h'
--- a/sql/backup/image_info.h	2008-11-25 16:37:46 +0000
+++ b/sql/backup/image_info.h	2008-12-04 23:14:30 +0000
@@ -83,7 +83,7 @@ public: // public interface
 
    // Examine contents of the catalogue.
 
-   bool has_db(const String&);
+   bool has_db(const String&) const;
 
    // Retrieve objects using their coordinates.
 

=== modified file 'sql/backup/kernel.cc'
--- a/sql/backup/kernel.cc	2008-12-04 16:50:07 +0000
+++ b/sql/backup/kernel.cc	2008-12-04 23:14:30 +0000
@@ -121,6 +121,8 @@ static int send_reply(Backup_restore_ctx
   @param[IN] thd        current thread object reference.
   @param[IN] lex        results of parsing the statement.
   @param[IN] backupdir  value of the backupdir variable from server.
+  @param[IN] overwrite  whether or not restore should overwrite existing
+                        DB with same name as in backup image
 
   @note This function sends response to the client (ok, result set or error).
 
@@ -132,7 +134,7 @@ static int send_reply(Backup_restore_ctx
  */
 
 int
-execute_backup_command(THD *thd, LEX *lex, String *backupdir)
+execute_backup_command(THD *thd, LEX *lex, String *backupdir, bool overwrite)
 {
   int res= 0;
   
@@ -212,6 +214,13 @@ execute_backup_command(THD *thd, LEX *le
 
   case SQLCOM_RESTORE:
   {
+
+    /*
+      Restore cannot be run on a slave while connected to a master.
+    */
+    if (obs::is_slave())
+      DBUG_RETURN(send_error(context, ER_RESTORE_ON_SLAVE));
+
     Restore_info *info= context.prepare_for_restore(backupdir, lex->backup_dir, 
                                                     thd->query);
     
@@ -220,7 +229,7 @@ execute_backup_command(THD *thd, LEX *le
     
     DEBUG_SYNC(thd, "after_backup_start_restore");
 
-    res= context.do_restore();      
+    res= context.do_restore(overwrite);      
 
     DEBUG_SYNC(thd, "restore_before_end");
 
@@ -325,7 +334,6 @@ int send_reply(Backup_restore_ctx &conte
     goto err;
   }
   my_eof(context.thd());                        // Never errors
-  context.report_cleanup();                     // Never errors
   DBUG_RETURN(0);
 
  err:
@@ -379,7 +387,8 @@ pthread_mutex_t Backup_restore_ctx::run_
 Backup_restore_ctx::Backup_restore_ctx(THD *thd)
  :Logger(thd), m_state(CREATED), m_thd_options(thd->options),
   m_error(0), m_remove_loc(FALSE), m_stream(NULL),
-  m_catalog(NULL), mem_alloc(NULL), m_tables_locked(FALSE)
+  m_catalog(NULL), mem_alloc(NULL), m_tables_locked(FALSE),
+  m_engage_binlog(FALSE)
 {
   /*
     Check for progress tables.
@@ -392,7 +401,7 @@ Backup_restore_ctx::Backup_restore_ctx(T
 Backup_restore_ctx::~Backup_restore_ctx()
 {
   close();
-  
+
   delete mem_alloc;
   delete m_catalog;  
   delete m_stream;
@@ -786,6 +795,25 @@ Backup_restore_ctx::prepare_for_restore(
 
   m_state= PREPARED_FOR_RESTORE;
 
+  /*
+    Do not allow slaves to connect during a restore.
+
+    If the binlog is turned on, write a RESTORE_EVENT as an
+    incident report into the binary log.
+
+    Turn off binlog during restore.
+  */
+  if (obs::is_binlog_engaged())
+  {
+    obs::disable_slave_connections(TRUE);
+
+    DEBUG_SYNC(m_thd, "after_disable_slave_connections");
+
+    obs::write_incident_event(m_thd, obs::RESTORE_EVENT);
+    m_engage_binlog= TRUE;
+    obs::engage_binlog(FALSE);
+  }
+
   return info;
 }
 
@@ -839,11 +867,18 @@ int Backup_restore_ctx::lock_tables_for_
   /*
     Open and lock the tables.
     
-    Note: simple_open_n_lock_tables() must be used here since we don't want
-    to do derived tables processing. Processing derived tables even leads 
-    to crashes as those reported in BUG#34758.
+    Note 1: It is important to not do derived tables processing here. Processing
+    derived tables even leads to crashes as those reported in BUG#34758.
+  
+    Note 2: Skiping tmp tables is also important because otherwise a tmp table
+    can occlude a regular table with the same name (BUG#33574).
   */ 
-  if (simple_open_n_lock_tables(m_thd,tables))
+  if (open_and_lock_tables_derived(m_thd, tables,
+                                   FALSE, /* do not process derived tables */
+                                   MYSQL_OPEN_SKIP_TEMPORARY 
+                                          /* do not open tmp tables */
+                                  )
+     )
   {
     fatal_error(ER_BACKUP_OPEN_TABLES,"RESTORE");
     return m_error;
@@ -924,6 +959,17 @@ int Backup_restore_ctx::close()
 
   using namespace backup;
 
+  /*
+    Allow slaves connect after restore is complete.
+  */
+  obs::disable_slave_connections(FALSE);
+
+  /*
+    Turn binlog back on iff it was turned off earlier.
+  */
+  if (m_engage_binlog)
+    obs::engage_binlog(TRUE);
+
   time_t when= my_time(0);
 
   // unlock tables if they are still locked
@@ -1155,11 +1201,14 @@ int Backup_restore_ctx::restore_triggers
 
   @pre @c prepare_for_restore() method was called.
 
+  @param[IN] overwrite whether or not restore should overwrite existing
+                       DB with same name as in backup image
+
   @returns 0 on success, error code otherwise.
 
   @todo Remove the @c reset_diagnostic_area() hack.
 */
-int Backup_restore_ctx::do_restore()
+int Backup_restore_ctx::do_restore(bool overwrite)
 {
   DBUG_ENTER("do_restore");
 
@@ -1179,6 +1228,24 @@ int Backup_restore_ctx::do_restore()
 
   DBUG_PRINT("restore", ("Restoring meta-data"));
 
+  // unless RESTORE... OVERWRITE: return error if database already exists
+  if (!overwrite) {
+    Image_info::Db_iterator *dbit= info.get_dbs();
+
+    if (!dbit) {
+      DBUG_RETURN(fatal_error(ER_OUT_OF_RESOURCES));
+    }
+
+    Image_info::Db *mydb;
+    while ((mydb= static_cast<Image_info::Db*>((*dbit)++))) {
+      if (!obs::check_db_existence(m_thd, &mydb->name())) {
+        delete dbit;
+        DBUG_RETURN(fatal_error(ER_RESTORE_DB_EXISTS, mydb->name().ptr()));
+      }
+    }
+    delete dbit;
+  }
+
   disable_fkey_constraints();                   // Never errors
 
   if (read_meta_data(info, s))
@@ -1254,6 +1321,8 @@ int Backup_restore_ctx::do_restore()
 
   report_stats_post(info);                      // Never errors
 
+  DEBUG_SYNC(m_thd, "before_restore_done");
+
   DBUG_RETURN(0);
 }
 
@@ -1931,6 +2000,7 @@ int bcat_create_item(st_bstream_image_he
       DBUG_PRINT("restore",
                  (" tablespace has changed on the server - aborting"));
       info->m_ctx.fatal_error(ER_BACKUP_TS_CHANGE, desc);
+      delete ts;
       return BSTREAM_ERROR;
     }
   }

=== modified file 'sql/backup/logger.h'
--- a/sql/backup/logger.h	2008-11-06 18:39:27 +0000
+++ b/sql/backup/logger.h	2008-11-14 15:02:10 +0000
@@ -5,6 +5,7 @@
 #include <backup_stream.h>
 #include <backup/error.h>
 #include "si_logs.h"
+#include "rpl_mi.h"
 
 namespace backup {
 
@@ -56,6 +57,7 @@ class Logger
    void report_state(enum_backup_state);
    void report_vp_time(time_t, bool);
    void report_binlog_pos(const st_bstream_binlog_pos&);
+   void report_master_binlog_pos(const st_bstream_binlog_pos&);
    void report_driver(const char *driver);
    void report_backup_file(char * path);
    void report_stats_pre(const Image_info&);
@@ -65,7 +67,6 @@ class Logger
      DBUG_ASSERT(backup_log);
      return backup_log->get_backup_id(); 
    }
-   void report_cleanup() { delete backup_log; }
    
    void save_errors();
    void stop_save_errors();
@@ -83,6 +84,10 @@ class Logger
   int write_message(log_level::value level , int error_code, const char *msg);
 
  private:
+  // Prevent copying/assigments
+  Logger(const Logger&);
+  Logger& operator=(const Logger&);
+
   util::SAVED_MYSQL_ERROR error;   ///< Used to store saved errors.
   bool m_save_errors;        ///< Flag telling if errors should be saved.
   bool m_push_errors;        ///< Should errors be pushed on warning stack?
@@ -94,12 +99,16 @@ inline
 Logger::Logger(THD *thd) 
   :m_type(BACKUP), m_state(CREATED),
    m_thd(thd), m_save_errors(FALSE), m_push_errors(TRUE), backup_log(0)
-{}
+{
+  clear_saved_errors();
+}
+ 
 
 inline
 Logger::~Logger()
 {
   clear_saved_errors();
+  delete backup_log;
 }
 
 /// Report unregistered message.
@@ -268,6 +277,22 @@ void Logger::report_binlog_pos(const st_
   DBUG_ASSERT(backup_log);
   backup_log->binlog_pos(pos.pos);
   backup_log->binlog_file(pos.file);
+}
+
+/**
+  Report master's binlog information.
+
+  @todo Write this information to the backup image file.
+*/
+inline
+void Logger::report_master_binlog_pos(const st_bstream_binlog_pos &pos)
+{
+  if (active_mi)
+  {
+    backup_log->master_binlog_pos(pos.pos);
+    backup_log->master_binlog_file(pos.file);
+    backup_log->write_master_binlog_info();
+  }
 }
 
 /**

=== modified file 'sql/backup/restore_info.h'
--- a/sql/backup/restore_info.h	2008-05-05 15:06:40 +0000
+++ b/sql/backup/restore_info.h	2008-11-13 13:02:36 +0000
@@ -47,6 +47,10 @@ class Restore_info: public backup::Image
 
  private:
 
+  // Prevent copying/assignments
+  Restore_info(const Restore_info&);
+  Restore_info& operator=(const Restore_info&);
+
   friend int backup::restore_table_data(THD*, Restore_info&, 
                                         backup::Input_stream&);
   friend int ::bcat_add_item(st_bstream_image_header*,

=== modified file 'sql/backup/stream.h'
--- a/sql/backup/stream.h	2008-10-15 20:00:48 +0000
+++ b/sql/backup/stream.h	2008-11-13 13:02:36 +0000
@@ -98,7 +98,7 @@ class Stream: public fd_stream
   ::String  *m_path;
   int     m_flags;  ///< flags used when opening the file
   size_t  m_block_size;
-  Logger  m_log;
+  Logger&  m_log;
 
   friend int stream_write(void*, bstream_blob*, bstream_blob);
   friend int stream_read(void*, bstream_blob*, bstream_blob);

=== modified file 'sql/backup/stream_v1.c'
--- a/sql/backup/stream_v1.c	2008-09-30 08:08:16 +0000
+++ b/sql/backup/stream_v1.c	2008-11-13 13:02:36 +0000
@@ -1277,9 +1277,8 @@ int bstream_wr_meta_data(backup_stream *
     CHECK_WR_RES(bstream_wr_item_def(s,cat,PER_TABLE_ITEM,item));
   }
 
+wr_error:
   bcat_iterator_free(cat,iter);
-
-  wr_error:
 
   return ret;
 }

=== modified file 'sql/lex.h'
--- a/sql/lex.h	2008-07-09 07:12:43 +0000
+++ b/sql/lex.h	2008-11-17 09:57:51 +0000
@@ -389,6 +389,7 @@ static SYMBOL symbols[] = {
   { "OUT",              SYM(OUT_SYM)},
   { "OUTER",		SYM(OUTER)},
   { "OUTFILE",		SYM(OUTFILE)},
+  { "OVERWRITE",		SYM(OVERWRITE_SYM)},
   { "OWNER",		SYM(OWNER_SYM)},
   { "PACK_KEYS",	SYM(PACK_KEYS_SYM)},
   { "PARSER",           SYM(PARSER_SYM)},

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2008-12-04 16:50:07 +0000
+++ b/sql/log.cc	2008-12-04 23:14:30 +0000
@@ -29,6 +29,7 @@
 #include "rpl_filter.h"
 #include "rpl_rli.h"
 #include "sql_audit.h"
+#include "si_objects.h"
 
 #include <my_dir.h>
 #include <stdarg.h>
@@ -779,10 +780,18 @@ bool Log_to_csv_event_handler::
   bool need_close= FALSE;
   bool need_rnd_end= FALSE;
   Open_tables_state open_tables_backup;
+  ulonglong save_thd_options;
   bool save_time_zone_used;
   char *host= current_thd->security_ctx->host; // host name
   char *user= current_thd->security_ctx->user; // user name
 
+  /*
+    Turn the binlog off and don't replicate the
+    updates to the backup logs.
+  */
+  save_thd_options= thd->options;
+  thd->options&= ~OPTION_BIN_LOG;
+
   save_time_zone_used= thd->time_zone_used;
   bzero(& table_list, sizeof(TABLE_LIST));
   table_list.alias= table_list.table_name= BACKUP_HISTORY_LOG_NAME.str;
@@ -857,6 +866,11 @@ bool Log_to_csv_event_handler::
   if (history_data->start)
   {
     MYSQL_TIME time;
+    /*
+      Set time ahead a few hours to allow backup purge test to test
+      PURGE BACKUP LOGS BEFORE command.
+    */
+    DBUG_EXECUTE_IF("set_log_time", history_data->start= my_time(0) + 100000;);
     my_tz_OFFSET0->gmt_sec_to_TIME(&time, (my_time_t)history_data->start);
 
     table->field[ET_OBH_FIELD_START_TIME]->set_notnull();
@@ -952,6 +966,12 @@ err:
     close_performance_schema_table(thd, & open_tables_backup);
 
   thd->time_zone_used= save_time_zone_used;
+
+  /*
+    Turn binlog back on if disengaged.
+  */
+  thd->options= save_thd_options;
+
   return result;
 }
 
@@ -1097,6 +1117,322 @@ err:
   return result;
 }
 
+/**
+  Delete the current row from a log table.
+
+  This method is used to delete a row from a log that is being
+  accessed as a table. The row to be deleted is the current
+  row that the handler is pointing to via tbl->record[0].
+
+  Note: The handler must be positioned correctly and the
+        tbl->record[0] must be fetched by the appropriate
+        method (e.g., hdl->next()). 
+
+  @param[IN]  hdl   Table handler.
+  @param[IN]  tbl   Table class.
+
+  @returns Result of delete operation
+*/
+static bool delete_current_log_row(handler *hdl, TABLE *tbl)
+{
+  bool result= 0;
+
+  /*
+    Tell the handler to allow deletes for this log table
+    by turning off log table flag.
+  */
+  hdl->extra(HA_EXTRA_ALLOW_LOG_DELETE);
+  result= hdl->ha_delete_row(tbl->record[0]);
+  hdl->extra(HA_EXTRA_MARK_AS_LOG_TABLE);
+  return result;
+}
+
+/**
+  Perform a table scan of the backup log tables for deleting rows.
+
+  This method is a helper method designed to delete rows from the
+  backup logs when the destination includes writing to tables.
+
+  The method is designed to work with either the backup_history or
+  backup_progress log. The log is specified using the @c log_name
+  parameter and should be either BACKUP_HISTORY_LOG_NAME or
+  BACKUP_PROGRESS_LOG_NAME.
+
+  There are three ways this method can be used. The choice of which of 
+  the operations to run depends on the values of the parameters as stated.
+  1. Delete rows whose backup_id is < a given value. This is used
+     for @c PURGE BACKUP LOGS TO <@c backup_id>.
+     To use this method, set @c backup_id to the value passed from the
+     command, @c delete_exact_row = FALSE, and @c datetime_val = 0. 
+  2. Delete rows in the log where backuip_id is == to a given value.
+     This is used when cascading deletes from the backup_history log 
+     to the backup_progress log. 
+     To use this method, set @c backup_id to the value of the rows needing
+     deletion, @c delete_exact_row = TRUE, and @c datetime_val = 0. 
+  3. Delete rows whose start_time < a given value. This is used for
+     @c PURGE BACKUP LOGS BEFORE <datetimeval>.
+     To use this method, set @c backup_id = 0, @c delete_exact_row = FALSE, 
+     and @c datetime_val = value passed from the command. 
+
+  @note Deleting rows by date is limited to the backup_history table.
+
+  @param[IN]  THD                 The current thread
+  @param[IN]  log_name            is used to determine which log to process 
+                                  (backup_history or backup_progress).
+  @param[IN]  backup_id           value specified on the command for deleting 
+                                  rows by id or value for exact match 
+  @param[IN]  datetime_val        value specified on the command for deleting 
+                                  rows by date
+  @param[IN]  delete_exact_row    if TRUE, use the comparison for the log 
+                                  column backup_id_in_row == @c backup_id else 
+                                  use the comparison backup_id_in_row < 
+                                  @c backup_id.
+  @param[OUT] num                 Number of rows affected.
+
+  @returns TRUE if error
+*/
+static bool del_bup_log_row(THD *thd, 
+                            LEX_STRING log_name, 
+                            ulonglong backup_id, 
+                            my_time_t datetime_val,
+                            bool delete_exact_row,
+                            int *rows)
+{
+  TABLE_LIST table_list;
+  handler *hdl;
+  TABLE *tbl;
+  uint result= 0;
+  int num_rows= 0;
+  Open_tables_state open_tables_backup;
+  MYSQL_TIME tmp;
+
+  DBUG_ASSERT((my_strcasecmp(system_charset_info, log_name.str, 
+               BACKUP_HISTORY_LOG_NAME.str) == 0) ||
+              (my_strcasecmp(system_charset_info, log_name.str, 
+               BACKUP_PROGRESS_LOG_NAME.str) == 0));
+
+  /*
+    Setup table list for open.
+  */
+  bzero(&table_list, sizeof(TABLE_LIST));
+  table_list.alias= table_list.table_name= log_name.str;
+  table_list.table_name_length= log_name.length;
+
+  table_list.lock_type= TL_WRITE_CONCURRENT_INSERT;
+
+  table_list.db= MYSQL_SCHEMA_NAME.str;
+  table_list.db_length= MYSQL_SCHEMA_NAME.length;
+
+  tbl= open_performance_schema_table(thd, &table_list,
+                                       &open_tables_backup);
+  hdl= tbl->file;
+  hdl->extra(HA_EXTRA_MARK_AS_LOG_TABLE);
+
+  /*
+    Get time zone conversion of value to compare for
+    PURGE BACKUP LOGS BEFORE <datetime>.
+  */
+  bzero(&tmp, sizeof(MYSQL_TIME));
+  thd->variables.time_zone->gmt_sec_to_TIME(&tmp, datetime_val);
+
+  /*
+    Begin table scan.
+  */
+  result= hdl->ha_rnd_init(1);
+  result= hdl->rnd_next(tbl->record[0]);
+  while (result != HA_ERR_END_OF_FILE)
+  {
+    // backup_id is field number 0 in both logs.
+    ulonglong id= tbl->field[0]->val_int();
+    /*
+      Delete by id.
+    */
+    if (!datetime_val)
+    {
+      /*
+        Here we delete a specific row. For example, a specific
+        row in the backup_history log as the result of a 
+        cascade delete initiated from backup_history log.
+      */
+      if (delete_exact_row)
+      {
+        if (id == backup_id) // delete log row
+        {
+          result= delete_current_log_row(hdl, tbl);
+          if (result)
+            goto error;
+        }
+      }
+      /*
+        Here we execute the delete all rows 'to' a specific
+        id, e.g. PURGE BACKUP LOGS TO 17 -- we delete id < 17.
+      */
+      else if (id < backup_id)
+      {
+        result= delete_current_log_row(hdl, tbl);
+        if (result)
+          goto error;
+        num_rows++;
+      }
+    }
+    /*
+      Delete by date
+    */
+    else  
+    {
+      MYSQL_TIME time;      
+
+      DBUG_ASSERT(my_strcasecmp(system_charset_info, log_name.str, 
+                  BACKUP_HISTORY_LOG_NAME.str) == 0);
+
+      tbl->field[ET_OBH_FIELD_START_TIME]->get_date(&time, TIME_NO_ZERO_DATE);
+      if (my_time_compare(&time, &tmp) < 0)
+      {
+        /*
+          When deleting by date for the backup_history table,
+          we must also delete rows from the backup_progress table
+          for this backup id.
+        */
+        if ((my_strcasecmp(system_charset_info, log_name.str, 
+             BACKUP_HISTORY_LOG_NAME.str) == 0) &&
+            opt_backup_progress_log && 
+            (log_backup_output_options & LOG_TABLE))
+        {
+          int r= 0;
+
+          del_bup_log_row(thd, BACKUP_PROGRESS_LOG_NAME, 
+                          id, 0, TRUE, &r);
+        }
+        result= delete_current_log_row(hdl, tbl);
+        if (result)
+          goto error;
+        num_rows++;
+      }
+    }
+    result= hdl->rnd_next(tbl->record[0]);
+  }
+error:
+  int res_end= hdl->ha_rnd_end();
+  *rows= num_rows;
+  close_performance_schema_table(thd, &open_tables_backup);
+  return (result != HA_ERR_END_OF_FILE) ? result : res_end;
+}
+
+/**
+  Remove all rows from the backup logs.
+
+  This method removes (via truncate) all data from the backup logs. It checks
+  if the backup logs are turned on and if the log_backup_output_option is set
+  to include writing to tables. If these conditions are true, each log 
+  (backup_history, backup_progress) is truncated.
+
+  @param[IN] THD  current thread
+
+  @returns TRUE = success, FALSE = failed
+*/
+bool Log_to_csv_event_handler::purge_backup_logs(THD *thd)
+{
+  TABLE_LIST tables;
+  bool res= FALSE;
+
+  if (opt_backup_history_log && (log_backup_output_options & LOG_TABLE))
+  {
+    // need to truncate the table.
+    tables.init_one_table("mysql", strlen("mysql"), 
+                          "backup_history", strlen("backup_history"),
+                          "backup_history", TL_READ);
+    alloc_mdl_locks(&tables, thd->mem_root);
+    res= mysql_truncate(thd, &tables, 1);
+    close_thread_tables(thd);
+    if (res)
+      goto err;
+  }
+  if (opt_backup_progress_log && (log_backup_output_options & LOG_TABLE))
+  {
+    // need to truncate the table.
+    tables.init_one_table("mysql", strlen("mysql"), 
+                          "backup_progress", strlen("backup_progress"),
+                          "backup_progress", TL_READ);
+    alloc_mdl_locks(&tables, thd->mem_root);
+    res= mysql_truncate(thd, &tables, 1);
+    close_thread_tables(thd);
+  }
+err:
+  return res;
+}
+
+/**
+  Purge backup logs of rows less than backup_id passed.
+
+  This method walks the backup log tables deleting all rows whose
+  backup id is less than @c backup_id passed. 
+
+  @param[IN]  THD                 The current thread
+  @param[IN]  backup_id           Value for backup id
+  @param[OUT] num                 Number of rows affected.
+
+  @retval num  Number of rows affected.
+
+  @returns TRUE if error
+*/
+bool 
+Log_to_csv_event_handler::purge_backup_logs_before_id(THD *thd, 
+                                                      ulonglong backup_id,
+                                                      int *rows)
+{
+  bool res= FALSE;
+
+  if (opt_backup_history_log && (log_backup_output_options & LOG_TABLE))
+  { 
+    res= del_bup_log_row(thd, BACKUP_HISTORY_LOG_NAME, 
+                         backup_id, 0, FALSE, rows);
+    if (res)
+      goto err;
+  }
+  if (opt_backup_progress_log && (log_backup_output_options & LOG_TABLE))
+  {
+    int r= 0;   //ignore this for progress log
+
+    res= del_bup_log_row(thd, BACKUP_PROGRESS_LOG_NAME, 
+                         backup_id, 0, FALSE, &r);
+  }
+err:
+  return res;
+}
+
+/**
+  Purge backup logs of rows previous to start date passed.
+
+  This method walks the backup log tables deleting all rows whose
+  start column value is less than @c t passed. 
+
+  Implementation Description: This method uses cascading delete 
+  functionality to remove rows from the backup_progress log when 
+  rows from the backup_history log are removed. Thus, only one 
+  call to delete rows from the logs is necessary.
+
+  @param[IN]  THD                 The current thread
+  @param[IN]  t                   Value for start datetime
+  @param[OUT] num                 Number of rows affected.
+
+  @retval num  Number of rows affected.
+
+  @returns TRUE if error
+*/
+bool 
+Log_to_csv_event_handler::purge_backup_logs_before_date(THD *thd, 
+                                                        my_time_t t,
+                                                        int *rows)
+{
+  bool res= FALSE;
+
+  if (opt_backup_history_log && (log_backup_output_options & LOG_TABLE))
+    res= del_bup_log_row(thd, BACKUP_HISTORY_LOG_NAME, 
+                         0, t, FALSE, rows);
+  return res;
+}
+
+
 bool Log_to_csv_event_handler::
   log_error(enum loglevel level, const char *format, va_list args)
 {
@@ -1257,12 +1593,55 @@ void Log_to_file_event_handler::flush_ba
     reopen log files 
 
     Where TRUE means perform open on history file (backup_history) and
-    FALSE means perform open on the progress file (backkup_progress).
+    FALSE means perform open on the progress file (backup_progress).
   */
   mysql_backup_history_log.reopen_file(TRUE);
   mysql_backup_progress_log.reopen_file(FALSE);
 }
 
+/**
+  Purge the backup logs of all data.
+
+  This method truncates the backup log files. It will only do so if the
+  log_backup_output_options includes logging to FILE. It also checks to
+  see if each log is turned on (backup_history and backup_progress) and
+  if so, truncates it. Truncate in this case means resetting the size
+  to 0 bytes using my_chsize().
+
+  @returns TRUE = success, FALSE = failed.
+*/
+bool Log_to_file_event_handler::purge_backup_logs()
+{
+  bool res= FALSE;
+
+  if (opt_backup_history_log && (log_backup_output_options & LOG_FILE))
+  {
+    MYSQL_BACKUP_LOG *backup_log= logger.get_backup_history_log_file_handler();
+
+    pthread_mutex_lock(backup_log->get_log_lock());
+    res= my_sync(backup_log->get_file(), MYF(MY_WME));
+    if (!res)
+      res= my_chsize(backup_log->get_file(), 0, 0, MYF(MY_WME));
+    pthread_mutex_unlock(backup_log->get_log_lock());
+    if (res)
+      goto err;
+  }
+  if (opt_backup_progress_log && (log_backup_output_options & LOG_FILE))
+  {
+    MYSQL_BACKUP_LOG *backup_log= logger.get_backup_progress_log_file_handler();
+
+    pthread_mutex_lock(backup_log->get_log_lock());
+    res= my_sync(backup_log->get_file(), MYF(MY_WME));
+    if (!res)
+      res= my_chsize(backup_log->get_file(), 0, 0, MYF(MY_WME));
+    pthread_mutex_unlock(backup_log->get_log_lock());
+    if (res)
+      goto err;
+  }
+err:
+  return res;
+}
+
 void Log_to_file_event_handler::cleanup()
 {
   mysql_log.cleanup();
@@ -1412,6 +1791,91 @@ bool LOGGER::flush_backup_logs(THD *thd)
   return rc;
 }
 
+/**
+  Delete contents of backup logs.
+
+  This method deletes the data from the backup logs. This applies to both
+  log file and table destinations.
+
+  @param[IN]  thd  The current thread.
+
+  @returns TRUE if error.
+*/
+bool LOGGER::purge_backup_logs(THD *thd)
+{
+  my_bool res= FALSE;
+
+  DBUG_ENTER("LOGGER::purge_backup_logs");
+  /*
+    Here we need to truncate the files if writing to files.
+  */
+  res= file_log_handler->purge_backup_logs();
+  if (res)
+    goto err;
+
+  /*
+    We also need to truncate the table if writing to tables.
+  */
+  res= table_log_handler->purge_backup_logs(thd);
+
+err:
+  DBUG_RETURN(res);
+}
+
+/**
+  Delete contents of backup logs where backup id is less than a given id.
+
+  This method deletes the data from the backup logs where a backup id is 
+  less than the backup id specified. This applies only to table destinations.
+
+  @param[IN]  thd        The current thread.
+  @param[IN]  backup_id  The backup id to compare rows to.
+  @param[OUT] rows       The number of rows affected.
+
+  @retval  num  The number of rows affected.
+
+  @returns TRUE if error.
+*/
+bool LOGGER::purge_backup_logs_before_id(THD *thd, 
+                                         ulonglong backup_id, 
+                                         int *rows)
+{
+  my_bool res= FALSE;
+
+  DBUG_ENTER("LOGGER::purge_backup_logs_before_id");
+
+  res= table_log_handler->purge_backup_logs_before_id(thd, backup_id, rows);
+
+  DBUG_RETURN(res);
+}
+
+/**
+  Delete backup rows less than a certain date.
+
+  This method scans the backup history log and deletes the rows for those
+  operations that were created (start column) previous to the date specified in 
+  @c t.
+
+  @param[IN]  thd        The current thread.
+  @param[IN]  t          The date to compare rows to.
+  @param[OUT] rows       The number of rows affected.
+
+  @retval  rows  The number of rows affected.
+
+  @returns TRUE if error.
+*/
+bool LOGGER::purge_backup_logs_before_date(THD *thd, 
+                                           my_time_t t, 
+                                           int *rows)
+{
+  my_bool res= FALSE;
+
+  DBUG_ENTER("LOGGER::purge_backup_logs_before_date");
+
+  res= table_log_handler->purge_backup_logs_before_date(thd, t, rows);
+
+  DBUG_RETURN(res);
+}
 
 /*
   Log slow query with all enabled log event handlers
@@ -1652,6 +2116,7 @@ bool LOGGER::backup_progress_log_write(T
   else
     id= 0;                              /* Log from connect handler */
 
+
   lock_shared();
   while (*current_handler)
     error|= (*current_handler++)->
@@ -3606,7 +4071,7 @@ ulonglong MYSQL_BACKUP_LOG::get_next_bac
   else  // increment the counter
     id= m_next_id + 1;
 
-  DBUG_EXECUTE_IF("set_backup_id", id= 500;);
+  DBUG_EXECUTE_IF("set_backup_id", id= obs::is_slave() ? 600 : 500;);
 
   /* 
     Write the new value to the file

=== modified file 'sql/log.h'
--- a/sql/log.h	2008-10-27 13:06:21 +0000
+++ b/sql/log.h	2008-10-28 14:17:05 +0000
@@ -268,6 +268,14 @@ private:
   time_t last_time;
 };
 
+/*
+  Values for the type enum. This reflects the order of the enum 
+  declaration in the PURGE BACKUP LOGS command.
+*/
+#define TYPE_ENUM_PURGE_BACKUP_LOGS       1
+#define TYPE_ENUM_PURGE_BACKUP_LOGS_ID    2
+#define TYPE_ENUM_PURGE_BACKUP_LOGS_DATE  3
+
 class MYSQL_BACKUP_LOG: public MYSQL_LOG
 {
 public:
@@ -307,6 +315,8 @@ public:
   }
   ulonglong get_next_backup_id();
   my_bool check_backup_logs(THD *thd);
+  File get_file() { return log_file.file; }
+  inline pthread_mutex_t* get_log_lock() { return &LOCK_log; }
 
 private:
   bool write_int(uint num);
@@ -577,6 +587,13 @@ public:
                                    longlong progress,
                                    int error_num,
                                    const char *notes);
+  bool purge_backup_logs(THD *thd);
+  bool purge_backup_logs_before_id(THD *thd, 
+                                   ulonglong backup_id, 
+                                   int *rows);
+  bool purge_backup_logs_before_date(THD *thd, 
+                                     my_time_t t, 
+                                     int *rows);
 
   int activate_log(THD *thd, uint log_type);
 
@@ -630,6 +647,7 @@ public:
 
   void flush();
   void flush_backup_logs();
+  bool purge_backup_logs();
   void init_pthread_objects();
   MYSQL_QUERY_LOG *get_mysql_slow_log() { return &mysql_slow_log; }
   MYSQL_QUERY_LOG *get_mysql_log() { return &mysql_log; }
@@ -684,6 +702,13 @@ public:
   void init_log_tables();
   bool flush_logs(THD *thd);
   bool flush_backup_logs(THD *thd);
+  bool purge_backup_logs(THD *thd);
+  bool purge_backup_logs_before_id(THD *thd, 
+                                   ulonglong backup_id, 
+                                   int *rows);
+  bool purge_backup_logs_before_date(THD *thd, 
+                                     my_time_t t, 
+                                     int *rows);
   /* Perform basic logger cleanup. this will leave e.g. error log open. */
   void cleanup_base();
   /* Free memory. Nothing could be logged after this function is called */

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2008-12-04 16:50:07 +0000
+++ b/sql/log_event.cc	2008-12-04 23:14:30 +0000
@@ -9138,12 +9138,11 @@ Incident_log_event::description() const
 {
   static const char *const description[]= {
     "NOTHING",                                  // Not used
-    "LOST_EVENTS"
+    "LOST_EVENTS",
+    "RESTORE_ON_MASTER"
   };
 
   DBUG_PRINT("info", ("m_incident: %d", m_incident));
-
-  DBUG_ASSERT((size_t) m_incident <= sizeof(description)/sizeof(*description));
 
   return description[m_incident];
 }

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2008-12-04 16:50:07 +0000
+++ b/sql/mysqld.cc	2008-12-04 23:14:30 +0000
@@ -513,6 +513,7 @@ my_bool opt_old_style_user_limits= 0, tr
 volatile bool mqh_used = 0;
 my_bool opt_noacl;
 my_bool sp_automatic_privileges= 1;
+my_bool disable_slaves= 0;
 
 ulong opt_binlog_rows_event_max_size;
 const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
@@ -3244,6 +3245,7 @@ SHOW_VAR com_status_vars[]= {
   {"prepare_sql",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PREPARE]), SHOW_LONG_STATUS},
   {"purge",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE]), SHOW_LONG_STATUS},
   {"purge_before_date",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE_BEFORE]), SHOW_LONG_STATUS},
+  {"purge_bup_log",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE_BACKUP_LOGS]), SHOW_LONG_STATUS},
   {"release_savepoint",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
   {"rename_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
   {"rename_user",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_USER]), SHOW_LONG_STATUS},
@@ -5848,7 +5850,9 @@ enum options_mysqld
   OPT_DEADLOCK_SEARCH_DEPTH_SHORT,
   OPT_DEADLOCK_SEARCH_DEPTH_LONG,
   OPT_DEADLOCK_TIMEOUT_SHORT,
-  OPT_DEADLOCK_TIMEOUT_LONG
+  OPT_DEADLOCK_TIMEOUT_LONG,
+  OPT_BACKUP_HISTORY_LOG_FILE,
+  OPT_BACKUP_PROGRESS_LOG_FILE
 };
 
 
@@ -6116,6 +6120,16 @@ Disable with --skip-large-pages.",
   {"general_log_file", OPT_GENERAL_LOG_FILE,
    "Log connections and queries to given file.", (uchar**) &opt_logname,
    (uchar**) &opt_logname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"backup_history_log_file", OPT_BACKUP_HISTORY_LOG_FILE,
+   "Log backup history to a given file.", 
+   (uchar**) &opt_backup_history_logname,
+   (uchar**) &opt_backup_history_logname, 0, GET_STR, 
+   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"backup_progress_log_file", OPT_BACKUP_PROGRESS_LOG_FILE,
+   "Log backup progress to a given file.", 
+   (uchar**) &opt_backup_progress_logname,
+   (uchar**) &opt_backup_progress_logname, 0, GET_STR, 
+   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"log-bin", OPT_BIN_LOG,
    "Log update queries in binary format. Optional (but strongly recommended "
    "to avoid replication problems if server's hostname changes) argument "
@@ -8264,7 +8278,7 @@ mysqld_get_one_option(int optid,
   {
     if (!argument || !argument[0])
     {
-      log_backup_output_options= LOG_FILE;
+      log_backup_output_options= LOG_TABLE;
       log_backup_output_str= log_output_typelib.type_names[1];
     }
     else

=== modified file 'sql/rpl_constants.h'
--- a/sql/rpl_constants.h	2007-03-29 18:31:09 +0000
+++ b/sql/rpl_constants.h	2008-10-28 18:14:14 +0000
@@ -11,6 +11,9 @@ enum Incident {
   /** There are possibly lost events in the replication stream */
   INCIDENT_LOST_EVENTS,
 
+  /** Restore event: Restore has occurred on the master during replication */
+  INCIDENT_RESTORE_EVENT,
+
   /** Shall be last event of the enumeration */
   INCIDENT_COUNT
 };

=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc	2008-11-18 19:41:51 +0000
+++ b/sql/set_var.cc	2008-12-04 23:14:30 +0000
@@ -76,7 +76,7 @@ extern ulong ndb_report_thresh_binlog_me
 #endif
 
 extern CHARSET_INFO *character_set_filesystem;
-
+extern my_bool disable_slaves;
 
 static DYNAMIC_ARRAY fixed_show_vars;
 static HASH system_variable_hash;
@@ -552,6 +552,8 @@ static sys_var_thd_ulonglong	sys_tmp_tab
 					   &SV::tmp_table_size);
 static sys_var_bool_ptr  sys_timed_mutexes(&vars, "timed_mutexes",
                                     &timed_mutexes);
+static sys_var_bool_ptr  sys_disable_slaves(&vars, "disable_slave_connections",
+                                             &disable_slaves);
 static sys_var_const_str	sys_version(&vars, "version", server_version);
 static sys_var_const_str	sys_version_comment(&vars, "version_comment",
                                             MYSQL_COMPILATION_COMMENT);
@@ -2398,7 +2400,15 @@ void sys_var_log_state::set_default(THD 
     WARN_DEPRECATED(thd, 7,0, "@@log_slow_queries", "'@@slow_query_log'");
 
   pthread_mutex_lock(&LOCK_global_system_variables);
-  logger.deactivate_log_handler(thd, log_type);
+  /*
+    Default for general and slow log is OFF.
+    Default for backup logs is ON.
+  */
+  if ((this == &sys_var_backup_history_log) ||
+      (this == &sys_var_backup_progress_log))
+    logger.activate_log_handler(thd, log_type);
+  else
+    logger.deactivate_log_handler(thd, log_type);
   pthread_mutex_unlock(&LOCK_global_system_variables);
 }
 
@@ -2561,7 +2571,8 @@ bool update_sys_var_str_path(THD *thd, s
   var_str->value= res;
   var_str->value_length= str_length;
   my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
-  if (file_log && log_state)
+  if ((file_log && log_state) ||
+      (backup_log && log_state))
   {
     /*
       Added support for backup log types.

=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt	2008-11-21 19:05:10 +0000
+++ b/sql/share/errmsg.txt	2008-12-04 23:14:30 +0000
@@ -6416,7 +6416,23 @@ ER_BACKUP_BINLOG
         eng "Error on accessing binlog during BACKUP"
         nor "Lesing av binlog feilet under BACKUP"
         norwegian-ny "Lesing av binlog feila under BACKUP"
-
+ER_BACKUP_LOG_OUTPUT
+  eng "Removing backup log entries by date or backup_id requires logging to tables."
+ER_BACKUP_PURGE_DATETIME
+  eng "The datetime specified is invalid for the '%-.64s' command."
+ER_BACKUP_LOGS_DELETED
+  eng "Backup log entries deleted: "
+ER_BACKUP_LOGS_TRUNCATED
+  eng "All backup log entries have been deleted"
+ER_MASTER_BLOCKING_SLAVES
+  eng "The master is not allowing slave connections."
+ER_RESTORE_ON_MASTER
+  eng "A restore operation was initiated on the master."
+ER_RESTORE_ON_SLAVE
+  eng "A restore operation was attempted on a slave during replication. You must stop the slave prior to running a restore."
+ER_NONUNIQ_DB 42000 S1009
+        eng "Not unique database: '%-.192s'"
+ER_RESTORE_DB_EXISTS
+  eng "Database \'%-.64s\' already exists. Use OVERWRITE flag to overwrite."
 ER_QUERY_CACHE_DISABLED
 	eng "Query cache is disabled; restart the server with query_cache_type=1 to enable it"
-

=== modified file 'sql/si_logs.cc'
--- a/sql/si_logs.cc	2008-10-15 20:00:48 +0000
+++ b/sql/si_logs.cc	2008-10-30 17:53:24 +0000
@@ -133,6 +133,26 @@ bool Backup_log::write_progress(const ch
                                           error_num, notes);
 }
 
+/**
+  Write master's binlog file and position to progress log.
+
+  @returns results of logging function (i.e., TRUE if error)
+*/
+bool Backup_log::write_master_binlog_info()
+{
+  char buff[1024];
+  bool ret= FALSE;
+
+  if (m_op_hist.master_binlog_file || m_op_hist.master_binlog_pos)
+  {
+    sprintf(buff, 
+      "Recording master binlog information. binlog file = '%s', position = %d.",
+      m_op_hist.master_binlog_file, m_op_hist.master_binlog_pos);
+    ret= write_progress(0, 0, 0, 0, 0, 0, (char *)&buff);
+  }
+  return ret;
+}
+
 /** 
   Report change of the state of operation
  

=== modified file 'sql/si_logs.h'
--- a/sql/si_logs.h	2008-10-15 20:00:48 +0000
+++ b/sql/si_logs.h	2008-10-30 17:53:24 +0000
@@ -58,6 +58,8 @@ struct st_backup_history
   time_t stop;                     ///< stop time of operation
   time_t vp_time;                  ///< point in time validation was assured
   String driver_name;              ///< list of backup engines used
+  int master_binlog_pos;           ///< position in the binary log
+  char *master_binlog_file;        ///< name of the master's binary log file
 };
 
 
@@ -112,6 +114,12 @@ public:
                       longlong progress,
                       int error_num,
                       const char *notes);
+
+  /*
+    Write master's binlog position and file if recorded earlier.
+  */
+  bool write_master_binlog_info();
+
   /*
     Check the backup logs (as tables).
   */
@@ -126,6 +134,11 @@ public:
   void error_num(int code) { m_op_hist.error_num= code; }
   void binlog_pos(unsigned long int pos) { m_op_hist.binlog_pos= pos; }
   void binlog_file(char *file);
+  void master_binlog_pos(unsigned long int pos) 
+  { 
+    m_op_hist.master_binlog_pos= pos; 
+  }
+  void master_binlog_file(char *file);
   void num_objects(int num) { m_op_hist.num_objects= num; }
   void size(longlong s) { m_op_hist.size= s; }
   void start(time_t when);
@@ -190,6 +203,22 @@ void Backup_log::binlog_file(char *file)
 {
   if (strlen(file) > 0)
     m_op_hist.binlog_file= file;
+}
+
+/** 
+  Report master's binlog position at validity point.
+
+  This method saves the binlog file name in the history data.
+
+  @param[IN] file Binlog file name.
+
+  @note If the file name is 0|NULL, nothing is saved in the history data.
+*/
+inline
+void Backup_log::master_binlog_file(char *file)
+{
+  if (strlen(file) > 0)
+    m_op_hist.master_binlog_file= file;
 }
 
 #endif // SI_LOGS_H_

=== modified file 'sql/si_objects.cc'
--- a/sql/si_objects.cc	2008-12-04 13:49:57 +0000
+++ b/sql/si_objects.cc	2008-12-04 23:14:30 +0000
@@ -24,6 +24,7 @@
 #include "sql_trigger.h"
 #include "sp.h"
 #include "sp_head.h" // for sp_add_to_query_tables().
+#include "rpl_mi.h"
 
 #ifdef HAVE_EVENT_SCHEDULER
 #include "events.h"
@@ -33,6 +34,8 @@
 
 DDL_blocker_class *DDL_blocker= NULL;
 
+extern my_bool disable_slaves;
+
 ///////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////
 
@@ -3031,6 +3034,201 @@ int Name_locker::release_name_locks()
     unlock_table_names(m_thd);
   }
   DBUG_RETURN(0);
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+//
+// Implementation: Replication methods.
+//
+
+///////////////////////////////////////////////////////////////////////////
+
+/*
+  Replication methods
+*/
+
+/**
+  Turn on or off logging for the current thread.
+
+  This method can be used to turn logging on or off in situations where it is
+  necessary to prevent some operations from being logged, e.g.
+  BACKUP DATABASE.
+
+  @param[IN] enable  TRUE = turn on, FALSE = turn off
+
+  @returns 0
+*/
+int engage_binlog(bool enable)
+{
+  int ret= 0;
+  THD *thd= current_thd;
+
+  if (enable)
+    thd->options|= OPTION_BIN_LOG;
+  else
+    thd->options&= ~OPTION_BIN_LOG;
+  return ret;
+}
+
+/**
+  Check if binlog is enabled for the current thread.
+
+  This method can be used to check to see if logging is enabled and operate
+  as a gate for those areas of code that are conditional on whether logging is
+  enabled (or disabled).
+
+  @returns   TRUE  if logging is enabled and binlog is open
+  @returns   FALSE if logging is turned off or binlog is closed
+*/
+bool is_binlog_engaged()
+{
+  THD *thd= current_thd;
+
+  return (thd->options & OPTION_BIN_LOG) && mysql_bin_log.is_open();
+}
+
+/**
+  Check if current server is executing as a slave.
+
+  This method can be used to detect when running as a slave. This means that
+  the server is configured to act as a slave. This can make it easier to
+  organize the code for specialized sections where running as a slave requires
+  additional work, prohibiting backup and restore operations, or error
+  conditions.
+
+  @returns   TRUE  if operating as a slave
+*/
+bool is_slave()
+{
+  bool running= FALSE;
+
+#ifdef HAVE_REPLICATION
+  if (active_mi)
+  {
+    pthread_mutex_lock(&LOCK_active_mi);
+    running= (active_mi->slave_running == MYSQL_SLAVE_RUN_CONNECT);
+    pthread_mutex_unlock(&LOCK_active_mi);
+  }
+#endif
+  return running;
+}
+
+/**
+  Check if any slaves are connected.
+
+  This method can be used to detect whether there are slaves attached to the
+  current server. This will allow the code to know if replication is active.
+
+  @returns  int number of slaves currently attached
+*/
+int num_slaves_attached()
+{
+  THD *thd= current_thd;
+
+  Ed_result ed_result;
+  LEX_STRING sql_text= LXS_INIT("SELECT CONCAT(COUNT(1)) "
+                                "FROM INFORMATION_SCHEMA.PROCESSLIST"
+                                "WHERE LCASE(command) = LCASE('Binlog Dump')");
+
+  if (run_service_interface_sql(thd, &sql_text, &ed_result) ||
+      ed_result.get_warnings().elements > 0)
+  {
+    /* Should be no warnings. */
+
+    /*
+      XXX: now zero is returned if there are warnings. Probably, that
+      should be changed and error flag (-1) should be returned.
+    */
+    return 0;
+  }
+
+  Ed_result_set *ed_result_set= ed_result.get_cur_result_set();
+
+  if (!ed_result_set || ed_result_set->data()->elements < 1)
+    return 0;
+
+  Ed_row *ed_row= ed_result_set->get_cur_row();
+  const LEX_STRING *num_slaves_str= ed_row->get_column(0);
+
+  char *buffer= thd->strmake(num_slaves_str->str, num_slaves_str->length + 1);
+  return atoi(buffer);
+}
+
+/**
+  Disable or enable connection of new slaves to the master.
+
+  This method can be used to temporarily prevent new slaves from connecting to
+  the master. This can allow operations such as RESTORE to prevent new slaves
+  from attaching during the execution of RESTORE.
+
+  @param[IN] disable  TRUE = turn off, FALSE = turn on
+
+  @returns value of disable_slaves (TRUE | FALSE)
+*/
+int disable_slave_connections(bool disable)
+{
+  // Protect with a mutex?
+  disable_slaves= disable ? 1 : 0;
+  return disable_slaves;
+}
+
+/**
+  Write an incident event in the binary log.
+
+  This method can be used to issue an incident event to inform the slave
+  that an unusual event has occurred on the master. For example an incident
+  event could represent that a restore has been issued on the master. This
+  should force the slave to stop and allow the user to analyze the effect
+  of the restore on the master and take the appropriate steps to correct
+  the slave (e.g. running the same restore on the slave.
+
+  @param[IN] thd            The current thread
+  @param[IN] incident_enum  The indicent being reported
+
+  @retval FALSE on success.
+  @retval TRUE on error.
+*/
+int write_incident_event(THD *thd, incident_events incident_enum)
+{
+  bool res= FALSE;
+
+#ifdef HAVE_REPLICATION
+  Incident incident;
+
+  /*
+    Generate an incident log event (gap event) to signal the slave
+    that a restore has been issued on the master.
+  */
+  switch (incident_enum){
+    case NONE:
+      incident= INCIDENT_NONE;
+      break;
+    case LOST_EVENTS:
+      incident= INCIDENT_LOST_EVENTS;
+      break;
+    case RESTORE_EVENT:
+      incident= INCIDENT_RESTORE_EVENT;
+      break;
+    default:   // fail safe : should not occur
+      incident= INCIDENT_NONE;
+      break;
+  }
+  DBUG_PRINT("write_incident_event()", ("Before write_incident_event()."));
+  /*
+    Don't write this unless binlog is engaged.
+  */
+  if (incident && is_binlog_engaged())
+  {
+    LEX_STRING msg;
+    msg.str= (char *)ER(ER_RESTORE_ON_MASTER);
+    msg.length = strlen(ER(ER_RESTORE_ON_MASTER));
+    Incident_log_event ev(thd, incident, msg);
+    res= mysql_bin_log.write(&ev);
+    mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
+  }
+#endif
+  return res;
 }
 
 ///////////////////////////////////////////////////////////////////////////

=== modified file 'sql/si_objects.h'
--- a/sql/si_objects.h	2008-11-27 16:45:16 +0000
+++ b/sql/si_objects.h	2008-12-04 23:14:30 +0000
@@ -478,6 +478,53 @@ private:
   void free_table_list(TABLE_LIST*);
 };
 
+///////////////////////////////////////////////////////////////////////////
+
+//
+// Replication methods.
+//
+
+/*
+  Turn on or off logging for the current thread. 
+*/
+int engage_binlog(bool enable);
+
+/*
+  Check if binlog is enabled for the current thread. 
+*/
+bool is_binlog_engaged();
+
+/*
+  Check if current server is executing as a slave. 
+*/
+bool is_slave();
+
+/*
+  Check if any slaves are connected. 
+*/
+int num_slaves_attached();
+
+/*
+  Disable or enable connection of new slaves to the master. 
+*/
+int disable_slave_connections(bool disable);
+
+/**
+  Enumeration of the incidents that can occur on the master.
+*/
+enum incident_events {
+  NONE,          // Indicates there was no incident 
+  LOST_EVENTS,   // Indicates lost events 
+  RESTORE_EVENT, // Indicates a restore has executed on the master
+  COUNT          // Value counts the enumerations
+};
+
+/*
+  Write incident event to signal slave an unusual event has been issued 
+  on the master.
+*/
+int write_incident_event(THD *thd, incident_events incident_enum);
+
 } // obs namespace
 
 #endif // SI_OBJECTS_H_

=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc	2008-11-24 23:00:01 +0000
+++ b/sql/sql_lex.cc	2008-12-04 23:14:30 +0000
@@ -3029,3 +3029,28 @@ bool LEX::is_partition_management() cons
            alter_info.flags == ALTER_REORGANIZE_PARTITION));
 }
 
+int LEX::add_db_to_list(LEX_STRING *name)
+{
+  DBUG_ASSERT(name);
+    
+  List_iterator<LEX_STRING> it(db_list);
+  LEX_STRING *copy;
+  
+  while ((copy= it++))
+   if (!my_strnncoll(system_charset_info, 
+                     (const uchar*) name->str, name->length , 
+                     (const uchar*) copy->str, copy->length ))
+   {    
+     my_error(ER_NONUNIQ_DB, MYF(0), name->str);
+     return ER_NONUNIQ_DB;
+   }
+
+  copy= (LEX_STRING*) sql_memdup(name, sizeof(LEX_STRING));
+  if (copy == NULL)
+    return ER_OUT_OF_RESOURCES;
+    
+  if (db_list.push_back(copy))
+    return ER_OUT_OF_RESOURCES;
+
+  return 0;
+}

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2008-11-24 23:00:01 +0000
+++ b/sql/sql_lex.h	2008-12-04 23:14:30 +0000
@@ -117,7 +117,7 @@ enum enum_sql_command {
   SQLCOM_SHOW_CREATE_EVENT, SQLCOM_SHOW_EVENTS,
   SQLCOM_SHOW_CREATE_TRIGGER,
   SQLCOM_ALTER_DB_UPGRADE,
-  SQLCOM_BACKUP, SQLCOM_RESTORE,
+  SQLCOM_BACKUP, SQLCOM_RESTORE, SQLCOM_PURGE_BACKUP_LOGS, 
 #ifdef BACKUP_TEST
   SQLCOM_BACKUP_TEST,
 #endif
@@ -1531,6 +1531,7 @@ struct LEX: public Query_tables_list
   LEX_STRING backup_dir;				/* For RESTORE/BACKUP */
   bool backup_compression;
   char* to_log;                                 /* For PURGE MASTER LOGS TO */
+  ulonglong backup_id;     /* For PURGE BACKUP LOGS */
   char* x509_subject,*x509_issuer,*ssl_cipher;
   String *wild;
   sql_exchange *exchange;
@@ -1877,6 +1878,13 @@ struct LEX: public Query_tables_list
     }
     return FALSE;
   }
+
+  void clear_db_list()
+  {
+    db_list.empty();
+  }
+
+  int add_db_to_list(LEX_STRING *name);
 };
 
 

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2008-12-04 16:50:07 +0000
+++ b/sql/sql_parse.cc	2008-12-04 23:14:30 +0000
@@ -44,7 +44,7 @@
   @defgroup Runtime_Environment Runtime Environment
   @{
 */
-int execute_backup_command(THD*, LEX*, String*);
+int execute_backup_command(THD*, LEX*, String*, bool);
 
 /* Used in error handling only */
 #define SP_TYPE_STRING(LP) \
@@ -2125,6 +2125,94 @@ mysql_execute_command(THD *thd)
     res = purge_master_logs_before_date(thd, (ulong)it->val_int());
     break;
   }
+  /*
+    Purge backup logs command.
+  */
+  case SQLCOM_PURGE_BACKUP_LOGS:
+  {
+    char buff[256];
+    int num= 0;
+    res= 0;
+
+    if (check_global_access(thd, SUPER_ACL))
+      goto error;
+
+    /*
+      If we are attempting to purge to a specified date or backup_id, we
+      must ensure the backup history log is turned on and is
+      being written to a table.
+    */
+    if (((lex->type == TYPE_ENUM_PURGE_BACKUP_LOGS_ID) ||
+         (lex->type == TYPE_ENUM_PURGE_BACKUP_LOGS_DATE)) &&
+         (opt_backup_history_log && !(log_backup_output_options & LOG_TABLE)))
+    {
+      my_error(ER_BACKUP_LOG_OUTPUT, MYF(0), ER(ER_BACKUP_LOG_OUTPUT));
+      goto error;
+    }
+
+    /*
+      Check the type of purge command and process accordingly.
+    */
+    switch (lex->type) {
+    case TYPE_ENUM_PURGE_BACKUP_LOGS:
+    {
+      if (sys_var_backupdir.value_length > 0)
+        res= logger.purge_backup_logs(thd);
+      break;
+    }
+    case TYPE_ENUM_PURGE_BACKUP_LOGS_ID:
+    {
+      res= logger.purge_backup_logs_before_id(thd, thd->lex->backup_id, &num);
+      break;
+    }
+    case TYPE_ENUM_PURGE_BACKUP_LOGS_DATE:
+    {
+      Item *it;
+
+      /*
+        Perform additional error checking for the 
+        PURGE BACKUP LOGS BEFORE <date> command.
+      */
+      it= (Item *)lex->value_list.head();
+      if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
+          it->check_cols(1))
+      {
+        my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE BACKUP LOGS BEFORE");
+        goto error;
+      }
+      it= new Item_func_unix_timestamp(it);
+
+      /*
+        it is OK to only emulate fix_fields, because we need only
+        value of constant
+      */
+      it->quick_fix_field();
+
+      if ((ulong)it->val_int() == 0)
+      {
+        my_error(ER_BACKUP_PURGE_DATETIME, MYF(0), "PURGE BACKUP LOGS BEFORE");
+        goto error;
+      }
+
+      my_time_t t= (ulong)it->val_int();
+
+      res= logger.purge_backup_logs_before_date(thd, t, &num);
+      break;
+    }
+    }
+
+    /*
+      Check result. 
+    */
+    if (res)
+      goto error;
+    if (lex->type == TYPE_ENUM_PURGE_BACKUP_LOGS)
+      my_sprintf(buff, (buff, "%s.", ER(ER_BACKUP_LOGS_TRUNCATED)));
+    else
+      my_sprintf(buff, (buff, "%s %d.", ER(ER_BACKUP_LOGS_DELETED), num));
+    my_ok(thd, num, 0, buff);
+    break;
+  }
 #endif
   case SQLCOM_SHOW_WARNS:
   {
@@ -2225,11 +2313,29 @@ mysql_execute_command(THD *thd)
                         sys_var_backupdir.value_length);
     backupdir.length(sys_var_backupdir.value_length);
 
+    /* Used to specify if RESTORE should overwrite existing db with same name */
+    bool overwrite_restore= false;
+
+    Item *it= (Item *)lex->value_list.head();
+
+    // Item only set for RESTORE in sql_yacc.yy, no error checking of
+    // item necessary
+    if (it)
+    {
+      /*
+        it is OK to only emulate fix_fields, because we need only
+        value of constant
+      */
+      it->quick_fix_field();
+
+      if ((int8)it->val_int() == 1)
+        overwrite_restore= true;
+    }
     /*
       Note: execute_backup_command() sends a correct response to the client
       (either ok, result set or error message).
      */ 
-    if (execute_backup_command(thd, lex, &backupdir))
+    if (execute_backup_command(thd, lex, &backupdir, overwrite_restore))
       goto error;
     break;
   }

=== modified file 'sql/sql_repl.cc'
--- a/sql/sql_repl.cc	2008-10-20 09:16:47 +0000
+++ b/sql/sql_repl.cc	2008-10-28 18:14:14 +0000
@@ -28,6 +28,7 @@ my_bool opt_sporadic_binlog_dump_fail = 
 #ifndef DBUG_OFF
 static int binlog_dump_count = 0;
 #endif
+extern my_bool disable_slaves;
 
 /*
     fake_rotate_event() builds a fake (=which does not exist physically in any
@@ -470,6 +471,17 @@ void mysql_binlog_send(THD* thd, char* l
     goto err;
   }
 #endif
+
+  /*
+    Tell the connecting slave the master cannot accept any connections
+    if disable_slaves == TRUE.
+  */
+  if (disable_slaves)
+  {
+     errmsg= "Master does not allow slaves to connect.";
+     my_errno= ER_MASTER_BLOCKING_SLAVES;
+     goto err;
+  }
 
   if (!mysql_bin_log.is_open())
   {

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2008-11-19 16:32:01 +0000
+++ b/sql/sql_yacc.yy	2008-12-04 23:14:30 +0000
@@ -974,6 +974,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  OUTER
 %token  OUTFILE
 %token  OUT_SYM                       /* SQL-2003-R */
+%token  OVERWRITE_SYM
 %token  OWNER_SYM
 %token  PACK_KEYS_SYM
 %token  PAGE_SYM
@@ -6422,8 +6423,6 @@ slave_until_opts:
 
 restore:
           RESTORE_SYM
-          FROM
-          TEXT_STRING_sys
           {
             LEX *lex= Lex;
             if (lex->sphead)
@@ -6432,18 +6431,37 @@ restore:
               MYSQL_YYABORT;
             }
             lex->sql_command = SQLCOM_RESTORE;
-            lex->db_list.empty();
-            lex->backup_dir = $3; 
+            lex->clear_db_list();
+          }
+          FROM
+          TEXT_STRING_sys 
+          opt_overwrite
+          {
+            Lex->backup_dir = $4; 
           }
         ;
 
-backup:
-          BACKUP_SYM
-          DATABASE
-          database_list
-          TO_SYM
-          TEXT_STRING_sys
-          opt_compression
+opt_overwrite:
+          /* empty */ 
+          {         
+            LEX *lex= Lex;
+            Item *it= new Item_int((int8) 0);
+
+            lex->value_list.empty();
+            lex->value_list.push_front(it);
+          }
+        | OVERWRITE_SYM 
+          {
+            LEX *lex= Lex;
+            Item *it= new Item_int((int8) 1);
+
+            lex->value_list.empty();
+            lex->value_list.push_front(it);
+           }
+         ;
+
+backup:   
+          BACKUP_SYM 
           {
             LEX *lex= Lex;
             if (lex->sphead)
@@ -6452,7 +6470,15 @@ backup:
               MYSQL_YYABORT;
             }
             lex->sql_command = SQLCOM_BACKUP;
-            lex->backup_dir = $5; 
+            lex->clear_db_list();
+          }
+          DATABASE
+          database_list 
+          TO_SYM 
+          TEXT_STRING_sys
+          opt_compression
+          {
+            Lex->backup_dir = $6;
           }
         | BACKUP_TEST_SYM
           database_list
@@ -6485,29 +6511,19 @@ opt_compression_algorithm:
 
 database_list:
           '*'
-          {
-            Lex->db_list.empty();
-          }
+          {}
         | database_ident_list
         ;
 
 database_ident_list:
           ident
           {
-            LEX *lex= Lex;
-            LEX_STRING* ls= (LEX_STRING*) sql_memdup(&$1, sizeof(LEX_STRING));
-            if (ls == NULL)
-              MYSQL_YYABORT;
-            lex->db_list.empty();
-            if (lex->db_list.push_back(ls))
+            if (Lex->add_db_to_list(&$1))
               YYABORT;
           }
         | database_ident_list ',' ident
           {
-            LEX_STRING *ls= (LEX_STRING*) sql_memdup(&$3, sizeof(LEX_STRING));
-            if (ls == NULL)
-              MYSQL_YYABORT;
-            if (Lex->db_list.push_back(ls))
+            if (Lex->add_db_to_list(&$3))
               YYABORT;
           }
         ;
@@ -10813,10 +10829,32 @@ purge:
             lex->type=0;
             lex->sql_command = SQLCOM_PURGE;
           }
-          purge_options
-          {}
-        ;
+          purge_options {}
+          | PURGE BACKUP_SYM LOGS_SYM 
+          {
+            LEX *lex=Lex;
+            lex->type=TYPE_ENUM_PURGE_BACKUP_LOGS;
+            lex->sql_command = SQLCOM_PURGE_BACKUP_LOGS;
+          }
+          purge_bup_log_option {}
+          ; 
 
+purge_bup_log_option:
+          {}
+          | TO_SYM NUM_literal
+          {
+            LEX *lex= Lex;
+            lex->backup_id= (ulonglong)$2->val_int(); 
+            lex->type=TYPE_ENUM_PURGE_BACKUP_LOGS_ID;
+          }
+          | BEFORE_SYM expr
+          {
+            LEX *lex= Lex;
+            lex->value_list.empty();
+            lex->value_list.push_front($2);
+            lex->type=TYPE_ENUM_PURGE_BACKUP_LOGS_DATE;
+          }
+          ;
 purge_options:
           master_or_binary LOGS_SYM purge_option
         ;

=== modified file 'storage/csv/ha_tina.cc'
--- a/storage/csv/ha_tina.cc	2008-10-20 19:13:22 +0000
+++ b/storage/csv/ha_tina.cc	2008-10-28 14:17:05 +0000
@@ -80,7 +80,6 @@ static handler *tina_create_handler(hand
                                     TABLE_SHARE *table, 
                                     MEM_ROOT *mem_root);
 
-
 /*****************************************************************************
  ** TINA tables
  *****************************************************************************/
@@ -169,6 +168,7 @@ static TINA_SHARE *get_share(const char 
     share->update_file_opened= FALSE;
     share->tina_write_opened= FALSE;
     share->data_file_version= 0;
+    share->allow_log_delete= FALSE;
     strmov(share->table_name, table_name);
     fn_format(share->data_file_name, table_name, "", CSV_EXT,
               MY_REPLACE_EXT|MY_UNPACK_FILENAME);
@@ -995,8 +995,13 @@ int ha_tina::delete_row(const uchar * bu
   share->rows_recorded--;
   pthread_mutex_unlock(&share->mutex);
 
-  /* DELETE should never happen on the log table */
-  DBUG_ASSERT(!share->is_log_table);
+  /* 
+     DELETE should never happen on the log table
+     UNLESS extra() has been called with HA_EXTRA_ALLOW_LOG_DELETE 
+     which sets allow_log_delete flag. The flag is reset with 
+     HA_EXTRA_MARK_AS_LOG_TABLE.     
+  */
+  DBUG_ASSERT(!share->is_log_table || share->allow_log_delete);
 
   DBUG_RETURN(0);
 }
@@ -1169,6 +1174,13 @@ int ha_tina::extra(enum ha_extra_functio
  {
    pthread_mutex_lock(&share->mutex);
    share->is_log_table= TRUE;
+   share->allow_log_delete= FALSE;
+   pthread_mutex_unlock(&share->mutex);
+ }
+ else if (operation == HA_EXTRA_ALLOW_LOG_DELETE)
+ {
+   pthread_mutex_lock(&share->mutex);
+   share->allow_log_delete= TRUE;
    pthread_mutex_unlock(&share->mutex);
  }
   DBUG_RETURN(0);

=== modified file 'storage/csv/ha_tina.h'
--- a/storage/csv/ha_tina.h	2008-06-28 11:00:59 +0000
+++ b/storage/csv/ha_tina.h	2008-10-28 14:17:05 +0000
@@ -50,6 +50,7 @@ typedef struct st_tina_share {
   bool crashed;             /* Meta file is crashed */
   ha_rows rows_recorded;    /* Number of rows in tables */
   uint data_file_version;   /* Version of the data file used */
+  bool allow_log_delete;
 } TINA_SHARE;
 
 struct tina_set {

=== modified file 'storage/falcon/BlobReference.cpp'
--- a/storage/falcon/BlobReference.cpp	2008-06-19 15:09:45 +0000
+++ b/storage/falcon/BlobReference.cpp	2008-10-31 15:42:42 +0000
@@ -157,5 +157,5 @@ int BlobReference::getReference(int size
 	for (n = 0; n < 64; n += 8)
 		*q++ = (UCHAR) (blobId >> n);
 
-	return q - buffer;
+	return (int)(q - buffer);
 }

=== modified file 'storage/falcon/Cache.cpp'
--- a/storage/falcon/Cache.cpp	2008-10-23 07:58:38 +0000
+++ b/storage/falcon/Cache.cpp	2008-10-31 15:42:42 +0000
@@ -102,6 +102,7 @@ Cache::Cache(Database *db, int pageSz, i
 	ioThreads = new Thread*[numberIoThreads];
 	memset(ioThreads, 0, numberIoThreads * sizeof(ioThreads[0]));
 	flushing = false;
+	recovering = false;
 	
 	try
 		{
@@ -221,6 +222,15 @@ Bdb* Cache::fetchPage(Dbb *dbb, int32 pa
 #endif
 
 	ASSERT (pageNumber >= 0);
+
+	if (recovering && pageType != PAGE_inventory &&
+		!PageInventoryPage::isPageInUse (dbb, pageNumber))
+		{
+		Log::debug ("During recovery, fetched page %d tablespace %d type %d marked free in PIP\n",
+			pageNumber, dbb->tableSpaceId, pageType);
+		PageInventoryPage::markPageInUse(dbb, pageNumber, 0);
+		}
+
 	int slot = pageNumber % hashSize;
 	LockType actual = lockType;
 	Sync sync (&syncObject, "Cache::fetchPage");
@@ -842,7 +852,7 @@ void Cache::ioThread(void)
 						
 					flushLock.unlock();
 					//Log::debug(" %d Writing %s %d pages: %d - %d\n", thread->threadId, (const char*) dbb->fileName, count, pageNumber, pageNumber + count - 1);
-					int length = p - buffer;
+					int length = (int)(p - buffer);
 					priority.schedule(PRIORITY_LOW);
 					
 					try

=== modified file 'storage/falcon/Cache.h'
--- a/storage/falcon/Cache.h	2008-10-02 22:15:11 +0000
+++ b/storage/falcon/Cache.h	2008-10-30 00:22:54 +0000
@@ -81,6 +81,7 @@ public:
 	int			numberBuffers;
 	bool		panicShutdown;
 	bool		flushing;
+	bool		recovering;
 
 protected:
 	Bdb*		findBuffer (Dbb *dbb, int pageNumber, LockType lockType);

=== modified file 'storage/falcon/CollationCaseless.cpp'
--- a/storage/falcon/CollationCaseless.cpp	2008-05-14 18:39:57 +0000
+++ b/storage/falcon/CollationCaseless.cpp	2008-10-31 15:42:42 +0000
@@ -98,7 +98,7 @@ int CollationCaseless::makeKey(Value *va
 	while (q > p && q [-1] == ' ')
 		--q;
 
-	l = q - p;
+	l = (int)(q - p);
 
 	for (int n = 0; n < l; ++n)
 		p [n] = caseTable [p [n]];

=== modified file 'storage/falcon/Database.cpp'
--- a/storage/falcon/Database.cpp	2008-10-23 07:58:38 +0000
+++ b/storage/falcon/Database.cpp	2008-10-29 23:25:13 +0000
@@ -1471,7 +1471,7 @@ void Database::truncateTable(Table *tabl
 	Sync syncDDLLock(&syncSysDDL, "Database::truncateTable(SysDDL)");
 	syncDDLLock.lock(Exclusive);
 	
-	// Lock syncScavenge before locking syncSysDDL, syncTables, or table->syncObject.
+	// Lock syncScavenge before locking syncTables, or table->syncObject.
 	// The scavenger locks syncScavenge  and then syncTables
 	// If we run out of record memory, forceRecordScavenge will eventually call table->syncObject.
 

=== modified file 'storage/falcon/DateTime.cpp'
--- a/storage/falcon/DateTime.cpp	2008-06-19 15:09:45 +0000
+++ b/storage/falcon/DateTime.cpp	2008-10-31 15:42:42 +0000
@@ -626,7 +626,7 @@ int DateTime::lookup(const char *string,
 
 	for (const char **tbl = table; *tbl; ++tbl)
 		if (match (temp, *tbl))
-			return tbl - table;
+			return (int)(tbl - table);
 
 	return -1;
 }
@@ -660,7 +660,7 @@ int DateTime::getString(int length, char
 			  time.tm_mon + 1, 
 			  time.tm_mday);
 
-	return strlen (buffer);
+	return (int)strlen(buffer);
 }
 
 
@@ -1056,7 +1056,7 @@ int DateTime::compare(DateTime when)
 
 DateTime DateTime::convert(const char *string)
 {
-	return convert (string, strlen (string));
+	return convert (string, (int)strlen (string));
 }
 
 const char* DateTime::getTimeZone()
@@ -1143,7 +1143,7 @@ int Time::getString(int length, char *bu
 			  time.tm_min, 
 			  time.tm_sec);
 
-	return strlen (buffer);
+	return (int)strlen (buffer);
 }
 
 const TimeZone* DateTime::findTimeZone(const char *string)

=== modified file 'storage/falcon/Dbb.cpp'
--- a/storage/falcon/Dbb.cpp	2008-10-16 02:53:35 +0000
+++ b/storage/falcon/Dbb.cpp	2008-10-30 00:22:54 +0000
@@ -1397,3 +1397,8 @@ void Dbb::updateSerialLogBlockSize(void)
 	header->serialLogBlockSize = database->serialLogBlockSize;
 	bdb->release(REL_HISTORY);
 }
+
+void Dbb::setCacheRecovering(bool state)
+{
+	cache->recovering = state;
+}

=== modified file 'storage/falcon/Dbb.h'
--- a/storage/falcon/Dbb.h	2008-07-24 08:45:03 +0000
+++ b/storage/falcon/Dbb.h	2008-10-30 00:22:54 +0000
@@ -184,6 +184,7 @@ public:
 	void	printPage(Bdb* bdb);
 	void	updateBlob(Section *blobSection, int recordNumber, Stream* blob, Transaction* transaction);
 	void	updateSerialLogBlockSize(void);
+	void	setCacheRecovering(bool state);
 	
 	Cache		*cache;
 	Database	*database;

=== modified file 'storage/falcon/DeferredIndex.cpp'
--- a/storage/falcon/DeferredIndex.cpp	2008-10-16 02:53:35 +0000
+++ b/storage/falcon/DeferredIndex.cpp	2008-11-14 15:38:44 +0000
@@ -862,6 +862,10 @@ void DeferredIndex::chill(Dbb *dbb)
 	leaf->count = 0;
 	root = leaf;
 	count = 0;
+	minValue = NULL;
+	maxValue = NULL;
+	haveMinValue = true;
+	haveMaxValue = true;
 
 	Log::log(LogInfo, "%d: Index chill: transaction %ld, index %ld, %ld bytes, address %p, vofs %llx\n",
 				dbb->database->deltaTime, transaction->transactionId, index->indexId, sizeEstimate, this, virtualOffset);

=== modified file 'storage/falcon/DeferredIndexWalker.cpp'
--- a/storage/falcon/DeferredIndexWalker.cpp	2008-10-16 02:53:35 +0000
+++ b/storage/falcon/DeferredIndexWalker.cpp	2008-11-03 00:33:04 +0000
@@ -110,10 +110,16 @@ DINode* DeferredIndexWalker::next(void)
 		{
 		nodePending = false;
 
-		return currentNode = (slot >= leaf->count) ? NULL : leaf->nodes[slot];
+		if (slot < leaf->count)
+			return (currentNode = leaf->nodes[slot]);
+
+		if (!deferredIndex->levels)
+			return NULL;  // Only one bucket and it is empty
+		// else the first leaf is empty.  Back up a level.
 		}
+	else
+		++slot;
 
-	++slot;
 	DIBucket *bucket;
 		
 	for (;;)

=== modified file 'storage/falcon/EditString.cpp'
--- a/storage/falcon/EditString.cpp	2008-05-14 18:39:57 +0000
+++ b/storage/falcon/EditString.cpp	2008-10-31 15:42:42 +0000
@@ -367,8 +367,8 @@ char* EditString::formatString(Value * v
 {
 	char		*temp;
 	const char	*from = value->getString (&temp);
-	int			fromLength = strlen (from);
-	int			fpos = 0, tpos = 0;
+	size_t		fromLength = strlen (from);
+	size_t		fpos = 0, tpos = 0;
 	char		c;
 	reset();
 

=== modified file 'storage/falcon/EncodedDataStream.cpp'
--- a/storage/falcon/EncodedDataStream.cpp	2008-05-30 15:40:29 +0000
+++ b/storage/falcon/EncodedDataStream.cpp	2008-10-31 15:42:42 +0000
@@ -1358,7 +1358,7 @@ void EncodedDataStream::encodeOpaque(int
 void EncodedDataStream::encodeEncoding(const UCHAR *encodedValue)
 {
 	const UCHAR *p = skip(encodedValue);
-	stream->putSegment(p - encodedValue, (const char*) encodedValue, true);
+	stream->putSegment((int)(p - encodedValue), (const char*) encodedValue, true);
 }
 
 INT64 EncodedDataStream::getInt64(int requiredScale)

=== modified file 'storage/falcon/Filter.cpp'
--- a/storage/falcon/Filter.cpp	2008-05-14 18:39:57 +0000
+++ b/storage/falcon/Filter.cpp	2008-10-31 15:42:42 +0000
@@ -133,7 +133,7 @@ int Filter::getWord(int bufferLength, ch
 
 	*q = 0;
 
-	return q - buffer;
+	return (int)(q - buffer);
 }
 
 void Filter::start()

=== modified file 'storage/falcon/FilterSet.cpp'
--- a/storage/falcon/FilterSet.cpp	2008-05-14 18:39:57 +0000
+++ b/storage/falcon/FilterSet.cpp	2008-10-31 15:42:42 +0000
@@ -152,5 +152,5 @@ JString FilterSet::stripSQL(const char *
 	while (end > sql && end [-1] != ')')
 		--end;
 
-	return JString (sql, end - sql);
+	return JString (sql, (int)(end - sql));
 }

=== modified file 'storage/falcon/FsbSort.cpp'
--- a/storage/falcon/FsbSort.cpp	2008-05-14 18:39:57 +0000
+++ b/storage/falcon/FsbSort.cpp	2008-10-31 15:42:42 +0000
@@ -69,7 +69,7 @@ FsbSort::FsbSort(CompiledStatement *stat
 
 	int *ptr = contextIds;
 	getStreams(&ptr);
-	numberContexts = ptr - contextIds;
+	numberContexts = (int)(ptr - contextIds);
 }
 
 FsbSort::~FsbSort()

=== modified file 'storage/falcon/IO.cpp'
--- a/storage/falcon/IO.cpp	2008-09-11 10:56:00 +0000
+++ b/storage/falcon/IO.cpp	2008-10-31 00:29:13 +0000
@@ -117,6 +117,19 @@ static char baseDir[PATH_MAX+1]={0};
 bool deleteFilesOnExit = false;
 bool inCreateDatabase = false;
 
+#ifdef _WIN32
+static int winUnlink(const char *file);
+static int winOpen(const char *filename, int flags,...);
+#endif
+
+#ifdef _WIN32
+#define POSIX_OPEN_FILE winOpen
+#define POSIX_UNLINK_FILE winUnlink
+#else
+#define POSIX_OPEN_FILE   ::open
+#define POSIX_UNLINK_FILE ::unlink
+#endif
+
 #ifdef _DEBUG
 #undef THIS_FILE
 static const char THIS_FILE[]=__FILE__;
@@ -186,7 +199,7 @@ bool IO::openFile(const char * name, boo
 	ASSERT(!inCreateDatabase);
 
 	fileName = getPath(name);
-	fileId = ::open (fileName, (readOnly) ? (O_RDONLY | O_BINARY) : (O_RDWR | O_BINARY));
+	fileId = POSIX_OPEN_FILE(fileName, (readOnly) ? (O_RDONLY | O_BINARY) : (O_RDWR | O_BINARY));
 
 	if (fileId < 0)
 		{
@@ -241,7 +254,7 @@ bool IO::createFile(const char *name)
 	Log::debug("IO::createFile: creating file \"%s\"\n", name);
 
 	fileName = getPath(name);
-	fileId = ::open (fileName.getString(),O_CREAT | O_RDWR | O_RANDOM | O_EXCL | O_BINARY,
+	fileId = POSIX_OPEN_FILE (fileName.getString(),O_CREAT | O_RDWR | O_RANDOM | O_EXCL | O_BINARY,
 						S_IREAD | S_IWRITE | S_IRGRP | S_IWGRP);
 
 
@@ -557,6 +570,7 @@ void IO::writeHeader(Hdr *header)
 void IO::deleteFile()
 {
 	deleteFile(fileName);
+	fileName="";
 }
 
 int IO::pread(int64 offset, int length, UCHAR* buffer)
@@ -675,10 +689,132 @@ void IO::sync(void)
 		traceOperation(TRACE_SYNC_END);
 }
 
+#ifdef _WIN32
+#define FALCON_DELETED_FILE "fdf"
+
+/*
+	The only safe way to delete file on Windows without invalidating open file 
+	handles is that:
+	- rename file to be deleted to a unique temporary name.
+	- open file it with FILE_FLAG_DELETE_ON_CLOSE
+	- close the file handle
+	Temp file will disappear as soon as last handle on it is closed.
+	This works only if files are opened with FILE_SHARE_DELETE flag.
+*/
+
+static int winUnlink(const char *file)
+{
+	DWORD attributes = GetFileAttributes(file);
+
+	// Bail out, if file does not exist.
+	if (attributes == INVALID_FILE_ATTRIBUTES)
+		return -1;
+
+	// If file is a symbolic link, just delete the link, but not the link target
+	if (attributes & FILE_ATTRIBUTE_REPARSE_POINT)
+		{
+		if(DeleteFile(file))
+			return 0;
+		return -1;
+		}
+
+	// Rename the file to unique name, then open with FILE_FLAG_DELETE_ON_CLOSE
+	// and close.
+	char  tmpDir[MAX_PATH];
+	strncpy(tmpDir, file, sizeof(tmpDir)-1);
+	char *p = strrchr(tmpDir ,SEPARATOR);
+	if (p)
+		*p = 0;
+	else
+		strcpy(tmpDir,".");
+
+	char  tmpFile[MAX_PATH];
+	if (GetTempFileName(tmpDir, FALCON_DELETED_FILE, 0, tmpFile))
+		{
+		if (MoveFileEx(file, tmpFile, MOVEFILE_REPLACE_EXISTING))
+			{
+			HANDLE hFile = CreateFile(tmpFile, 0,
+				FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+				NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);
+
+			if (hFile != INVALID_HANDLE_VALUE)
+				{
+				CloseHandle(hFile);
+				return 0;
+				}
+			}
+		else
+			DeleteFile(tmpFile);
+		}
+	
+	// Something went wrong. Try DeleteFile(), even if it can invalidate
+	// open file handles.
+	if(DeleteFile(file))
+		return 0;
+
+	return -1;
+}
+
+/* 
+	A wrapper for Posix open(). The reason it is there is the FILE_SHARE_DELETE 
+	flag used in CreateFile, which allows for  posixly-correct unlink
+	(that works with open files)
+*/
+static int winOpen(const char *filename, int flags,...)
+{
+	DWORD access;
+	if (flags & O_WRONLY)
+		access = GENERIC_WRITE;
+	else if (flags & O_RDWR)
+		access = GENERIC_READ|GENERIC_WRITE;
+	else
+		access = GENERIC_READ;
+
+	DWORD disposition;
+	if (flags & O_CREAT)
+		disposition = CREATE_NEW;
+	else
+		disposition = OPEN_EXISTING;
+
+	DWORD attributes;
+	if (flags & O_RANDOM)
+		attributes = FILE_FLAG_RANDOM_ACCESS;
+	else
+		attributes = FILE_ATTRIBUTE_NORMAL;
+
+	HANDLE hFile = CreateFile(filename, access, 
+		FILE_SHARE_DELETE, NULL, disposition, attributes, NULL);
+	
+	if (hFile == INVALID_HANDLE_VALUE)
+		{
+		switch(GetLastError())
+			{
+			case ERROR_ACCESS_DENIED:
+				errno = EACCES;
+				break;
+			case ERROR_FILE_NOT_FOUND:
+			case ERROR_PATH_NOT_FOUND:
+				errno = ENOENT;
+				break;
+			default:
+				errno = EINVAL;
+				break;
+			}
+		return -1;
+		}
+	return _open_osfhandle((intptr_t)hFile, 
+		flags & (_O_APPEND|_O_RDONLY|_O_TEXT));
+}
+
+#endif
+
 void IO::deleteFile(const char* fileName)
 {
-	JString path = getPath(fileName);
-	unlink(path.getString());
+	if(fileName && *fileName)
+		{
+		JString path = getPath(fileName);
+		POSIX_UNLINK_FILE(path.getString());
+		}
 }
 
 void IO::tracePage(Bdb* bdb)
@@ -810,3 +946,4 @@ uint16 IO::computeChecksum(Page *page, s
 	return (uint16) sum;
 
 }
+

=== modified file 'storage/falcon/Index.cpp'
--- a/storage/falcon/Index.cpp	2008-10-16 02:53:35 +0000
+++ b/storage/falcon/Index.cpp	2008-10-29 23:25:13 +0000
@@ -582,7 +582,7 @@ void Index::update(Record * oldRecord, R
 	IndexKey key(this);
 	makeKey (record, &key);
 
-	// If there is a duplicate in the old version chain, don't both with another
+	// If there is a duplicate in the old version chain, don't bother with another
 
 	if (duplicateKey (&key, oldRecord))
 		return;

=== modified file 'storage/falcon/IndexRootPage.cpp'
--- a/storage/falcon/IndexRootPage.cpp	2008-08-25 22:09:13 +0000
+++ b/storage/falcon/IndexRootPage.cpp	2008-10-31 15:42:42 +0000
@@ -1198,7 +1198,7 @@ void IndexRootPage::positionIndex(Dbb* d
 		offset = page->computePrefix (key, highKey);
 		}
 
-	walkIndex->setNodes(page->nextPage, page->length - ((UCHAR*) node.node - (UCHAR*) page->nodes), node.node);
+	walkIndex->setNodes(page->nextPage, page->length - (int)((UCHAR*) node.node - (UCHAR*) page->nodes), node.node);
 	bdb->release(REL_HISTORY);
 }
 

=== modified file 'storage/falcon/Log.h'
--- a/storage/falcon/Log.h	2007-11-29 22:51:08 +0000
+++ b/storage/falcon/Log.h	2008-11-13 13:27:13 +0000
@@ -38,6 +38,9 @@ static const int	LogScrub		= 128;
 static const int	LogException	= 256;
 static const int	LogScavenge		= 512;
 static const int	LogXARecovery	= 1024;
+static const int	LogMysqlInfo		= 0x20000000;
+static const int	LogMysqlWarning		= 0x40000000;
+static const int	LogMysqlError		= 0x80000000;
 
 typedef void (Listener) (int, const char*, void *arg);
 

=== modified file 'storage/falcon/MemMgr.cpp'
--- a/storage/falcon/MemMgr.cpp	2008-08-20 16:28:44 +0000
+++ b/storage/falcon/MemMgr.cpp	2008-11-03 00:34:05 +0000
@@ -55,7 +55,7 @@
 #include "LogStream.h"
 #endif
 
-static const int guardBytes = sizeof(long); // * 2048;
+static const size_t guardBytes = sizeof(long); // * 2048;
 
 #ifndef ASSERT
 #define ASSERT
@@ -112,7 +112,7 @@ struct Client {
 	};
 
 #ifdef _DEBUG
-	void* MemMgrPoolAllocateDebug (MemMgr *pool, unsigned int s, const char *file, int line)
+	void* MemMgrPoolAllocateDebug (MemMgr *pool, size_t s, const char *file, int line)
 	{
 		void *object = pool->allocateDebug(s, file, line);
 
@@ -120,12 +120,12 @@ struct Client {
 			printf("MemMgrAllocateDebug at %p\n", stopAddress);
 
 		if (traceFile)
-			fprintf(traceFile, "a %d %p\n", s, object);
+			fprintf(traceFile, "a " I64FORMAT " %p\n", (int64)s, object);
 
 		return object;
 	}
 
-	void* MemMgrAllocateDebug (unsigned int s, const char *file, int line)
+	void* MemMgrAllocateDebug (size_t s, const char *file, int line)
 	{
 		if(!memoryManagerAlive)
 			return malloc(s);
@@ -136,7 +136,7 @@ struct Client {
 			printf("MemMgrAllocateDebug at %p\n", stopAddress);
 
 		if (traceFile)
-			fprintf(traceFile, "a %d %p\n", s, object);
+			fprintf(traceFile, "a " I64FORMAT " %p\n", (int64)s, object);
 
 		return object;
 	}
@@ -159,7 +159,7 @@ struct Client {
 		memoryManager.releaseDebug (object);
 	}
 
-	void* MemMgrRecordAllocate (int size, const char *file, int line)
+	void* MemMgrRecordAllocate (size_t size, const char *file, int line)
 	{
 		return recordManager.allocateDebug (size, file, line);
 	}
@@ -169,12 +169,12 @@ struct Client {
 		recordManager.releaseDebug (record);
 	}
 #else
-	void* MemMgrPoolAllocate (MemMgr *pool, unsigned int s)
+	void* MemMgrPoolAllocate (MemMgr *pool, size_t s)
 	{
 		return pool->allocate (s);
 	}
 
-	void* MemMgrAllocate (unsigned int s)
+	void* MemMgrAllocate (size_t s)
 	{
 		if(!memoryManagerAlive)
 			return malloc(s);
@@ -190,7 +190,7 @@ struct Client {
 			memoryManager.release (object);
 	}
 
-	void* MemMgrRecordAllocate (int size, const char *file, int line)
+	void* MemMgrRecordAllocate (size_t size, const char *file, int line)
 	{
 		return recordManager.allocate (size);
 	}
@@ -346,10 +346,12 @@ MemMgr::~MemMgr(void)
 		*isAlive = false;
 }
 
-MemBlock* MemMgr::alloc(int length)
+MemBlock* MemMgr::alloc(size_t s)
 {
-	if (length <= 0)
-		throw SQLError (RUNTIME_ERROR, "illegal memory allocate for %d bytes", length);
+	if (s > INT_MAX)
+		throw SQLError (RUNTIME_ERROR, "illegal memory allocate for " I64FORMAT " bytes", (int64)s);
+
+	int length = (int) s;
 
 	Sync sync (&mutex, "MemMgr::alloc");
 	sync.lock(Exclusive);
@@ -522,9 +524,9 @@ MemBlock* MemMgr::alloc(int length)
 	return block;
 }
 
-void* MemMgr::allocate(int size)
+void* MemMgr::allocate(size_t size)
 {
-	int length = ROUNDUP(size, roundingSize) + OFFSET(MemBlock*, body) + guardBytes;
+	size_t length = ROUNDUP(size, roundingSize) + OFFSET(MemBlock*, body) + guardBytes;
 	MemBlock *memory;
 
 	ASSERT(signature == defaultSignature);
@@ -547,9 +549,9 @@ void* MemMgr::allocate(int size)
 	return &memory->body;
 }
 
-void* MemMgr::allocateDebug(int size, const char* fileName, int line)
+void* MemMgr::allocateDebug(size_t size, const char* fileName, int line)
 {
-	int length = ROUNDUP(size, roundingSize) + OFFSET(MemBlock*, body) + guardBytes;
+	size_t length = ROUNDUP(size, roundingSize) + OFFSET(MemBlock*, body) + guardBytes;
 	MemBlock *memory;
 
 	ASSERT(signature == defaultSignature);
@@ -563,7 +565,7 @@ void* MemMgr::allocateDebug(int size, co
 #endif
 
 	memset (&memory->body, INIT_BYTE, size);
-	int l = ABS(memory->length) - size - OFFSET(MemBlock*,body);
+	size_t l = ABS(memory->length) - size - OFFSET(MemBlock*,body);
 	ASSERT(l >= guardBytes && l < length - size + guardBytes + (int) sizeof (MemFreeBlock));
 	memset (&memory->body + size, GUARD_BYTE, l);
 	++blocksAllocated;

=== modified file 'storage/falcon/MemMgr.h'
--- a/storage/falcon/MemMgr.h	2008-08-06 11:53:21 +0000
+++ b/storage/falcon/MemMgr.h	2008-10-31 15:42:42 +0000
@@ -19,6 +19,7 @@
 
 #include "Mutex.h"
 #include "SyncObject.h"
+#include <limits.h>
 
 
 #ifndef MEM_DEBUG
@@ -135,12 +136,12 @@ public:
 	friend void  MemMgrLogDump();
 
 protected:
-	MemBlock*	alloc(int size);
+	MemBlock*	alloc(size_t size);
 	static void	corrupt(const char* text);
 	
 public:
-	void*		allocate(int size);
-	void*		allocateDebug(int size, const char* fileName, int line);
+	void*		allocate(size_t size);
+	void*		allocateDebug(size_t size, const char* fileName, int line);
 	void		releaseBlock(MemBlock *block);
 	void		validateBlock(MemBlock *block);
 	void		analyze (int mask, Stream *stream, InfoTable *summaryTable, InfoTable *detailTable);

=== modified file 'storage/falcon/MemoryManager.h'
--- a/storage/falcon/MemoryManager.h	2008-09-14 20:12:37 +0000
+++ b/storage/falcon/MemoryManager.h	2008-10-31 15:42:42 +0000
@@ -43,35 +43,35 @@ class MemMgr;
 struct MemObject;
 
 #ifdef _DEBUG
-	extern void* MemMgrAllocateDebug (unsigned int s, const char *file, int line);
-	extern void* MemMgrPoolAllocateDebug (MemMgr *pool, unsigned int s, const char *file, int line);
+	extern void* MemMgrAllocateDebug (size_t s, const char *file, int line);
+	extern void* MemMgrPoolAllocateDebug (MemMgr *pool, size_t s, const char *file, int line);
 	
 	WINSTATIC ALWAYS_INLINE void* operator new(size_t s) THROWS_BAD_ALLOC
-		{ return MemMgrAllocateDebug ((unsigned int) s, __FILE__, __LINE__); }
+		{ return MemMgrAllocateDebug (s, __FILE__, __LINE__); }
 		
 	WINSTATIC ALWAYS_INLINE void* operator new(size_t s, const int  &n) 
-		{ return MemMgrAllocateDebug ((unsigned int) s, __FILE__, __LINE__); }
+		{ return MemMgrAllocateDebug (s, __FILE__, __LINE__); }
 		
 	WINSTATIC ALWAYS_INLINE void* operator new(size_t s, const char *file, int line) 
-		{ return MemMgrAllocateDebug ((unsigned int) s, file, line); }
+		{ return MemMgrAllocateDebug (s, file, line); }
 		
 	WINSTATIC ALWAYS_INLINE void* operator new[](size_t s) THROWS_BAD_ALLOC
-		{ return MemMgrAllocateDebug ((unsigned int) s, __FILE__, __LINE__); }
+		{ return MemMgrAllocateDebug (s, __FILE__, __LINE__); }
 		
 	WINSTATIC ALWAYS_INLINE void* operator new[](size_t s, const char *file, int line) THROWS_BAD_ALLOC
-		{ return MemMgrAllocateDebug ((unsigned int) s, file, line); }
+		{ return MemMgrAllocateDebug (s, file, line); }
 
 	WINSTATIC ALWAYS_INLINE void* operator new(size_t s, MemMgr *pool) THROWS_BAD_ALLOC
-		{ return MemMgrPoolAllocateDebug (pool, (unsigned int) s, __FILE__, __LINE__); }
+		{ return MemMgrPoolAllocateDebug (pool, s, __FILE__, __LINE__); }
 
 	WINSTATIC ALWAYS_INLINE void* operator new(size_t s, MemMgr *pool, const char *file, int line) 
-		{ return MemMgrPoolAllocateDebug (pool, (unsigned int) s, file, line); }
+		{ return MemMgrPoolAllocateDebug (pool, s, file, line); }
 		
 	WINSTATIC ALWAYS_INLINE void* operator new[](size_t s, MemMgr *pool) THROWS_BAD_ALLOC
 		{ return MemMgrPoolAllocateDebug (pool, (unsigned int) s, __FILE__, __LINE__); }
 
 	WINSTATIC ALWAYS_INLINE void* operator new[](size_t s, MemMgr *pool, const char *file, int line) 
-		{ return MemMgrPoolAllocateDebug (pool, (unsigned int) s, file, line); }
+		{ return MemMgrPoolAllocateDebug (pool,  s, file, line); }
 
 #define POOL_NEW(arg) new(arg, THIS_FILE, __LINE__)
 #define NEW	new (THIS_FILE, __LINE__)
@@ -81,8 +81,8 @@ struct MemObject;
 #endif
 
 #else
-	extern void* MemMgrAllocate (unsigned int s);
-	extern void* MemMgrPoolAllocate (MemMgr *pool, unsigned int s);
+	extern void* MemMgrAllocate (size_t s);
+	extern void* MemMgrPoolAllocate (MemMgr *pool, size_t s);
 	
 	WINSTATIC ALWAYS_INLINE void* operator new(size_t s) THROWS_BAD_ALLOC
 		{ return MemMgrAllocate (s); }
@@ -91,7 +91,7 @@ struct MemObject;
 		{ return ::MemMgrPoolAllocate (pool, s); }
 
 	WINSTATIC ALWAYS_INLINE void* operator new[](size_t s, MemMgr *pool) THROWS_BAD_ALLOC
-		{ return ::MemMgrPoolAllocate (pool, s); }
+		{ return ::MemMgrPoolAllocate (pool,s); }
 
 	WINSTATIC ALWAYS_INLINE void* operator new(size_t s, const int  &n) THROWS_BAD_ALLOC
 		{ return ::MemMgrAllocate (s); }
@@ -118,7 +118,7 @@ extern void		MemMgrAnalyze(MemMgrWhat wh
 extern void		MemMgrRelease (void *object);
 extern void		MemMgrValidate (void *object);
 extern void		MemMgrAnalyze(int mask, Stream *stream);
-extern void*	MemMgrRecordAllocate (int size, const char *file, int line);
+extern void*	MemMgrRecordAllocate (size_t size, const char *file, int line);
 extern void		MemMgrRecordDelete (char *record);
 extern void		MemMgrSetMaxRecordMember (long long size);
 extern MemMgr*	MemMgrGetFixedPool (int id);

=== modified file 'storage/falcon/Record.cpp'
--- a/storage/falcon/Record.cpp	2008-10-27 18:00:09 +0000
+++ b/storage/falcon/Record.cpp	2008-10-29 23:25:13 +0000
@@ -849,7 +849,7 @@ void Record::setPriorVersion(Record* rec
 	ASSERT(false);
 }
 
-int Record::thaw(bool force)
+int Record::thaw(void)
 {
 	return 0;
 }

=== modified file 'storage/falcon/Record.h'
--- a/storage/falcon/Record.h	2008-10-24 05:35:38 +0000
+++ b/storage/falcon/Record.h	2008-10-29 23:25:13 +0000
@@ -88,7 +88,7 @@ public:
 	virtual Record*	getPriorVersion();
 	virtual Record*	getGCPriorVersion(void);
 	virtual	void	print(void);
-	virtual int		thaw(bool force = false);
+	virtual int		thaw(void);
 	virtual const char*	getEncodedRecord();
 	virtual int		setRecordData(const UCHAR *dataIn, int dataLength);
 	virtual void	serialize(Serialize* stream);

=== modified file 'storage/falcon/RecordScavenge.cpp'
--- a/storage/falcon/RecordScavenge.cpp	2008-10-24 05:06:52 +0000
+++ b/storage/falcon/RecordScavenge.cpp	2008-10-29 23:25:13 +0000
@@ -56,7 +56,7 @@ void RecordScavenge::inventoryRecord(Rec
 		uint64 age = baseGeneration - record->generation;
 		int size = record->size + sizeof(MemBigHeader);
 		
-		if (record->hasRecord(false) || record->state == recChilled)
+		if (record->hasRecord(false) || (record->state == recChilled))
 			size += sizeof(MemBigHeader);
 			
 		if (age != UNDEFINED && age < AGE_GROUPS)

=== modified file 'storage/falcon/RecordVersion.cpp'
--- a/storage/falcon/RecordVersion.cpp	2008-10-24 05:35:38 +0000
+++ b/storage/falcon/RecordVersion.cpp	2008-11-07 01:09:04 +0000
@@ -55,6 +55,9 @@ RecordVersion::RecordVersion(Table *tbl,
 		{
 		priorVersion->addRef();
 		recordNumber = oldVersion->recordNumber;
+
+		if (priorVersion->state == recChilled)
+			priorVersion->thaw();
 		
 		if (trans == priorVersion->getTransaction())
 			oldVersion->setSuperceded (true);
@@ -353,7 +356,7 @@ uint64 RecordVersion::getVirtualOffset()
 	return (virtualOffset);
 }
 
-int RecordVersion::thaw(bool force)
+int RecordVersion::thaw()
 {
 	Sync syncThaw(format->table->getSyncThaw(this), "RecordVersion::thaw");
 	syncThaw.lock(Exclusive);
@@ -370,7 +373,7 @@ int RecordVersion::thaw(bool force)
 	// true, then the record data can be restored from the serial log. If writePending
 	// is false, then the record data has been written to the data pages.
 	
-	if (trans && (trans->writePending || force))
+	if (trans && trans->writePending)
 		{
 		trans->addRef();
 		bytesRestored = trans->thaw(this);

=== modified file 'storage/falcon/RecordVersion.h'
--- a/storage/falcon/RecordVersion.h	2008-10-24 05:06:52 +0000
+++ b/storage/falcon/RecordVersion.h	2008-10-29 23:25:13 +0000
@@ -53,7 +53,7 @@ public:
 	virtual void		setPriorVersion (Record *oldVersion);
 	virtual void		setVirtualOffset(uint64 offset);
 	virtual uint64		getVirtualOffset();
-	virtual int			thaw(bool force = false);
+	virtual int			thaw(void);
 	virtual void		print(void);
 	virtual int			getSize(void);
 	virtual void		serialize(Serialize* stream);

=== modified file 'storage/falcon/RecoveryObjects.cpp'
--- a/storage/falcon/RecoveryObjects.cpp	2008-09-03 22:17:54 +0000
+++ b/storage/falcon/RecoveryObjects.cpp	2008-10-29 23:25:13 +0000
@@ -99,7 +99,7 @@ bool RecoveryObjects::isObjectActive(int
 	return object->pass1Count == object->currentCount;
 }
 
-static inline RecoveryPage * findInHashBucket(RecoveryPage *head, int objectNumber, int tableSpaceId)
+RecoveryPage* RecoveryObjects::findInHashBucket(RecoveryPage *head, int objectNumber, int tableSpaceId)
 {
 	for (RecoveryPage *object = head ; object; object = object->collision)
 		if (object->objectNumber == objectNumber && object->tableSpaceId == tableSpaceId)

=== modified file 'storage/falcon/RecoveryObjects.h'
--- a/storage/falcon/RecoveryObjects.h	2008-07-18 21:24:52 +0000
+++ b/storage/falcon/RecoveryObjects.h	2008-10-29 23:25:13 +0000
@@ -40,6 +40,7 @@ public:
 	void			reset();
 	bool			bumpIncarnation(int objectNumber, int tableSpaceId, int state, bool pass1);
 	void			clear();
+	RecoveryPage*	findInHashBucket(RecoveryPage *head, int objectNumber, int tableSpaceId);
 	RecoveryPage*	findRecoveryObject(int objectNumber, int tableSpaceId);
 	void			setActive(int objectNumber, int tableSpaceId);
 	void			setInactive(int objectNumber, int tableSpaceId);

=== modified file 'storage/falcon/SRLUpdateIndex.cpp'
--- a/storage/falcon/SRLUpdateIndex.cpp	2008-10-16 02:53:35 +0000
+++ b/storage/falcon/SRLUpdateIndex.cpp	2008-11-14 15:38:44 +0000
@@ -60,25 +60,39 @@ void SRLUpdateIndex::append(DeferredInde
 	uint64 virtualOffset = 0;
 	uint64 virtualOffsetAtEnd = 0;
 
-	// Remember where this is logged
-
-	virtualOffset = log->writeWindow->getNextVirtualOffset();
-
 	for (DINode *node = walker.next(); node;)
 		{
 		START_RECORD(srlUpdateIndex, "SRLUpdateIndex::append(2)");
+		
+		// Save the absolute offset of the DeferredIndex record within the serial log.
+		// This must be done inside the SerialLog::syncWrite lock set by START_RECORD().
+
+		if (virtualOffset == 0)
+			virtualOffset = log->startRecordVirtualOffset;
+
 		log->updateIndexUseVector(indexId, tableSpaceId, 1);
 		SerialLogTransaction *srlTrans = log->getTransaction(transaction->transactionId);
 		srlTrans->setTransaction(transaction);
 		ASSERT(transaction->writePending);
+		
+		// Set the record header fields
+		
 		putInt(tableSpaceId);
 		putInt(transaction->transactionId);
 		putInt(indexId);
 		putInt(idxVersion);
+		
+		// Initialize the length field, adjust with correct length later.
+		// Use a fixed-length integer to accommodate a larger number.
+		
 		UCHAR *lengthPtr = putFixedInt(0);
 		UCHAR *start = log->writePtr;
 		UCHAR *end = log->writeWarningTrack;
 
+		// Write the variable-length index node data. If the data length
+		// will extend past the end of the current window, start a new
+		// record.
+		
 		for (; node; node = walker.next())
 			{
 			if (log->writePtr + byteCount(node->recordNumber) +
@@ -93,10 +107,18 @@ void SRLUpdateIndex::append(DeferredInde
 		int len = (int) (log->writePtr - start);
 		//printf("SRLUpdateIndex::append tid %d, index %d, length %d, ptr %x (%x)\n",  transaction->transactionId, indexId, len, lengthPtr, org);
 		ASSERT(len >= 0);
-		putFixedInt(len, lengthPtr);
-		const UCHAR *p = lengthPtr;
-		ASSERT(getInt(&p) == len);
+
+		// Update the length field
+		
+		if (len > 0)
+			putFixedInt(len, lengthPtr);
+		
+		// Save the absolute offset of the end of the DeferredIndex record
+		
 		virtualOffsetAtEnd = log->writeWindow->getNextVirtualOffset();
+		
+		// End this serial log record and flush to disk. Force the creation of
+		// a new serial log window.
 		log->endRecord();
 		
 		if (node)
@@ -218,9 +240,9 @@ void SRLUpdateIndex::thaw(DeferredIndex*
 {
 	Sync sync(&log->syncWrite, "SRLUpdateIndex::thaw");
 	sync.lock(Exclusive);
+
 	uint64 virtualOffset = deferredIndex->virtualOffset;
 	int recordNumber = 0;  // a valid record number to get into the loop.
-	ASSERT(deferredIndex->virtualOffset);
 	Transaction *trans = deferredIndex->transaction;
 	TransId transId = trans->transactionId;
 	indexId = deferredIndex->index->indexId;
@@ -235,21 +257,25 @@ void SRLUpdateIndex::thaw(DeferredIndex*
 	
 	if (window == NULL)
 		{
-		Log::log("A window for DeferredIndex::virtualOffset=" I64FORMAT " could not be found.\n",
-		         deferredIndex->virtualOffset);
+		Log::log("Index thaw FAIL: A window for DeferredIndex::virtualOffset=" I64FORMAT " could not be found.\n", deferredIndex->virtualOffset);
 		log->printWindows();
-		
 		return;
 		}
-		
-	// Find the correct block within the window and set the offset using that block.
 
-	SerialLogBlock *block = window->firstBlock();
-	uint32 blockOffset = 0;
-	ASSERT( (UCHAR *) block == window->buffer);
+	// Location of the DeferredIndex within the window
+	
 	uint32 windowOffset = (uint32) (virtualOffset - window->virtualOffset);
-
-	while (windowOffset >= blockOffset + block->length)
+	
+	// Location of the block in which the DeferredIndex resides
+	
+	uint32 blockOffset = 0; 
+	
+	// Find the block in which the DeferredIndex resides, starting with the first
+	// block in the window. Accumulate each block's offset in blockOffset.
+	
+	SerialLogBlock *block = window->firstBlock();
+	
+	while (blockOffset + block->length <= windowOffset)
 		{
 		SerialLogBlock *prevBlock = block;
 		block = window->nextBlock(block);
@@ -257,21 +283,37 @@ void SRLUpdateIndex::thaw(DeferredIndex*
 		blockOffset += thisBlockOffset;
 		}
 
+	// Find the location of the DeferredIndex in the target block. Adjust for the
+	// offset of the data buffer within the block structure.
+	
 	uint32 offsetWithinBlock = (windowOffset - blockOffset - OFFSET(SerialLogBlock*, data));
+	
+	// Get the serial log version and set the input pointer to the specified offset within
+	// the target block. Activate the window, if necessary.
+	
 	control->setWindow(window, block, offsetWithinBlock);
 	ASSERT(control->input == window->buffer + windowOffset);
 	ASSERT(control->inputEnd <= window->bufferEnd);
 
-	// Read the SerialLogRecord type and header
-
-	UCHAR type = getInt();
-	ASSERT(type == srlUpdateIndex);
-	read();		// this read() is also in control->nextRecord() below.
+	// Now we are pointing at a serial log record, so read the entire record.
+	// Version records are written at the top of each block. If necessary,
+	// advance past the version record and read the SRLUpdateIndex record.
 
-	while (virtualOffset < deferredIndex->virtualOffsetAtEnd)
+	SerialLogRecord* srlRecord = control->nextRecord();
+	
+	if (srlRecord && srlRecord->type == srlVersion)
+		srlRecord = control->nextRecord();
+		
+	if (srlRecord)
+		ASSERT(srlRecord->type == srlUpdateIndex);
+	else
+		Log::log("Index thaw FAIL: SRLUpdateIndex record not found. DeferredIndex::virtualOffset=" I64FORMAT "\n", deferredIndex->virtualOffset);
+	
+	// The DeferredIndex may reside in several serial log records. Read each record and
+	// rebuild the index from the nodes stored within the record.
+	
+	while (srlRecord && virtualOffset < deferredIndex->virtualOffsetAtEnd)
 		{
-		sync.unlock();
-
 		// Read the header of the deferredIndex and validate.
 
 		ASSERT(transactionId == transId);
@@ -283,7 +325,7 @@ void SRLUpdateIndex::thaw(DeferredIndex*
 					
 		IndexKey indexKey(deferredIndex->index);
 
-		// Read each IndexKey and add it to the deferredIndex.   set ptr and end for nextKey()
+		// Read each IndexKey and add it to the deferredIndex. Set ptr and end for nextKey().
 
 		ptr = data;
 		end = ptr + dataLength;
@@ -291,13 +333,15 @@ void SRLUpdateIndex::thaw(DeferredIndex*
 		for (recordNumber = nextKey(&indexKey); recordNumber >= 0; recordNumber = nextKey(&indexKey))
 			deferredIndex->addNode(&indexKey, recordNumber);
 
-		sync.lock(Exclusive);
-
 		for (;;)
 			{
 			// Quit if there are no more SerialLogRecords for this DeferredIndex.
 
 			SerialLogWindow *inputWindow = control->inputWindow;
+
+			if (!inputWindow)
+				break;
+				
 			virtualOffset = inputWindow->virtualOffset + (control->input - inputWindow->buffer);
 
 			if (virtualOffset >= deferredIndex->virtualOffsetAtEnd)
@@ -305,9 +349,9 @@ void SRLUpdateIndex::thaw(DeferredIndex*
 
 			// Find the next SerialLogRecord of this deferredIndex.
 
-			SerialLogRecord *record = control->nextRecord();
+			srlRecord = control->nextRecord();
 
-			if ((record == this) && (transactionId == transId) && (indexId == deferredIndex->index->indexId))
+			if (srlRecord == this && transactionId == transId && indexId == deferredIndex->index->indexId)
 				break;
 			}
 		}

=== modified file 'storage/falcon/SRLUpdateRecords.cpp'
--- a/storage/falcon/SRLUpdateRecords.cpp	2008-10-24 05:06:52 +0000
+++ b/storage/falcon/SRLUpdateRecords.cpp	2008-11-14 15:38:44 +0000
@@ -76,6 +76,9 @@ int SRLUpdateRecords::thaw(RecordVersion
 	if (!window)
 		return 0;
 		
+	Sync sync(&log->syncWrite, "SRLUpdateRecords::thaw");
+	sync.lock(Exclusive);
+	
 	// Return pointer to record data
 
 	control->input = window->buffer + (record->getVirtualOffset() - window->virtualOffset);
@@ -94,14 +97,15 @@ int SRLUpdateRecords::thaw(RecordVersion
 	int dataLength   = control->getInt();
 	int bytesReallocated = 0;
 	
+	window->deactivateWindow();
+	sync.unlock();
+	
 	// setRecordData() handles race conditions with an interlocked compare and exchange,
 	// but check the state and record number anyway
 
 	if (record->state == recChilled && recordNumber == record->recordNumber)
 		bytesReallocated = record->setRecordData(control->input, dataLength);
 
-	window->deactivateWindow();
-
 	if (bytesReallocated > 0)
 		{
 		ASSERT(recordNumber == record->recordNumber);
@@ -124,10 +128,14 @@ void SRLUpdateRecords::append(Transactio
 {
 	uint32 chilledRecordsWindow = 0;
 	uint32 chilledBytesWindow   = 0;
-	uint32 windowNumber         = 0;
 	SerialLogTransaction *srlTrans = NULL;
 	int savepointId;
 	
+	// Generate one serial log record per write window. To ensure that
+	// chilled records are grouped by savepoint, start a new serial
+	// log record for each savepoint. Several serial log records may
+	// be generated for one savepoint.
+	
 	for (RecordVersion *record = records; record;)
 		{
 		START_RECORD(srlUpdateRecords, "SRLUpdateRecords::append");
@@ -160,7 +168,6 @@ void SRLUpdateRecords::append(Transactio
 			if (record->state == recChilled)
 				{
 				transaction->chillPoint = &record->nextInTrans;
-				
 				continue;
 				}
 				
@@ -169,7 +176,8 @@ void SRLUpdateRecords::append(Transactio
 			if (record->state == recNoChill)
 				continue;
 
-			// If this is a different savepoint, start another record
+			// If this is a different savepoint, break out of the inner loop
+			// and start another serial log record
 			
 			if (chillRecords && record->savePointId != savepointId)
 				break;
@@ -178,20 +186,34 @@ void SRLUpdateRecords::append(Transactio
 			tableSpaceId = table->dbb->tableSpaceId;
 			Stream stream;
 			
-			// Thawed records are indicated by a non-zero virtual offset, and
-			// are already in the serial log. If this record is to be re-chilled,
-			// then no need to get the record data or set the virtual offset.
+			// A non-zero virtual offset indicates that the record was previously
+			// chilled and thawed and is already in the serial log.
+			//
+			// If this record is being re-chilled, then there is no need to get
+			// the record data or set the virtual offset.
+			//
+			// If this record is being committed, then there is nothing to do.
 
-			if (chillRecords && record->state != recDeleted && record->virtualOffset != 0)
+			if (record->virtualOffset != 0)
 				{
-				int chillBytes = record->getEncodedSize();
-				chill(transaction, record, chillBytes);
-				log->chilledRecords++;
-				log->chilledBytes += chillBytes;
-				ASSERT(transaction->thawedRecords > 0);
-
-				if (transaction->thawedRecords)
-					transaction->thawedRecords--;
+				if (chillRecords && record->state != recDeleted)
+					{
+					int chillBytes = record->getEncodedSize();
+
+					chill(transaction, record, chillBytes);
+					
+					log->chilledRecords++;
+					log->chilledBytes += chillBytes;
+					
+					ASSERT(transaction->thawedRecords > 0);
+
+					if (transaction->thawedRecords)
+						transaction->thawedRecords--;
+					}
+				else
+					{
+					// Record is already in serial log
+					}
 
 				continue;
 				}
@@ -215,13 +237,15 @@ void SRLUpdateRecords::append(Transactio
 				 byteCount(stream.totalLength) + stream.totalLength >= end)
 				break;
 			
-			// Set the virtual offset of the record in the serial log
-
 			ASSERT(record->recordNumber >= 0);
 			ASSERT(log->writePtr > (UCHAR *)log->writeWindow->buffer);
+			
+			// Set the virtual offset of the record in the serial log
+
 			record->setVirtualOffset(log->writeWindow->currentLength + log->writeWindow->virtualOffset);
 			uint32 sectionId = table->dataSectionId;
 			log->updateSectionUseVector(sectionId, tableSpaceId, 1);
+			
 			putInt(tableSpaceId);
 			putInt(record->getPriorVersion() ? sectionId : -(int) sectionId - 1);
 			putInt(record->recordNumber);
@@ -233,14 +257,18 @@ void SRLUpdateRecords::append(Transactio
 				chilledRecordsWindow++;
 				chilledBytesWindow += stream.totalLength;
 				}
-			} // next record
+			} // next record version
 		
 		int len = (int) (log->writePtr - start);
 		
+		// The length field is 0, update if necessary
+		
 		if (len > 0)
 			putFixedInt(len, lengthPtr);
 		
-		if (record)
+		// Flush record data, if any, and force the creation of a new serial log window
+		
+		if (record && len > 0)
 			log->flush(true, 0, &sync);
 		else
 			sync.unlock();
@@ -250,9 +278,10 @@ void SRLUpdateRecords::append(Transactio
 			log->chilledRecords += chilledRecordsWindow;
 			log->chilledBytes   += chilledBytesWindow;
 			transaction->chilledRecords += chilledRecordsWindow;
-			windowNumber = (uint32)log->writeWindow->virtualOffset / SRL_WINDOW_SIZE;
+			transaction->chilledBytes += chilledBytesWindow;
+//			uint32 windowNumber = (uint32)log->writeWindow->virtualOffset / SRL_WINDOW_SIZE;
 			}
-		} // next window
+		} // next serial log record and write window
 }
 
 void SRLUpdateRecords::read(void)

=== modified file 'storage/falcon/SerialLog.cpp'
--- a/storage/falcon/SerialLog.cpp	2008-10-20 21:28:11 +0000
+++ b/storage/falcon/SerialLog.cpp	2008-11-14 15:38:44 +0000
@@ -131,6 +131,7 @@ SerialLog::SerialLog(Database *db, JStri
 	gophers = NULL;
 	wantToSerializeGophers = 0;
 	serializeGophers = 0;
+	startRecordVirtualOffset = 0;
 	
 	for (uint n = 0; n < falcon_gopher_threads; ++n)
 		{
@@ -217,7 +218,9 @@ void SerialLog::recover()
 	sync.lock(Exclusive);
 	recovering = true;
 	recoveryPhase = 0;	// Find last block and recovery block
-	
+
+	defaultDbb->setCacheRecovering(true);
+
 	// See if either or both files have valid blocks
 
 	SerialLogWindow *window1 = allocWindow(file1, 0);
@@ -414,7 +417,8 @@ void SerialLog::recover()
 		info->sectionUseVector.zap();
 		info->indexUseVector.zap();
 		}
-		
+
+	defaultDbb->setCacheRecovering(false);
 	Log::log("Recovery complete\n");
 	recoveryPhase = 0;	// Find last lock and recovery block
 }
@@ -708,6 +712,8 @@ void SerialLog::startRecord()
 	if (writeError)
 		throw SQLError(IO_ERROR_SERIALLOG, "Previous I/O error on serial log prevents further processing");
 
+	startRecordVirtualOffset = writeWindow->getNextVirtualOffset();
+	
 	if (writePtr == writeBlock->data)
 		putVersion();
 

=== modified file 'storage/falcon/SerialLog.h'
--- a/storage/falcon/SerialLog.h	2008-10-20 21:28:11 +0000
+++ b/storage/falcon/SerialLog.h	2008-11-14 15:38:44 +0000
@@ -224,6 +224,7 @@ public:
 	uint64				chilledBytes;
 	int32				wantToSerializeGophers;
 	int32				serializeGophers;
+	uint64				startRecordVirtualOffset;
 
 	TableSpaceInfo		*tableSpaces[SLT_HASH_SIZE];
 	TableSpaceInfo		*tableSpaceInfo;

=== modified file 'storage/falcon/SerialLogControl.cpp'
--- a/storage/falcon/SerialLogControl.cpp	2008-03-11 16:15:47 +0000
+++ b/storage/falcon/SerialLogControl.cpp	2008-11-11 22:33:27 +0000
@@ -337,6 +337,7 @@ SerialLogRecord* SerialLogControl::nextR
 	ASSERT(version > 0);
 	ASSERT(type < srlMax);
 	SerialLogRecord *record = records[type];
+	record->type = type;
 	record->read();
 	
 	if (debug)

=== modified file 'storage/falcon/SerialLogFile.cpp'
--- a/storage/falcon/SerialLogFile.cpp	2008-10-16 02:53:35 +0000
+++ b/storage/falcon/SerialLogFile.cpp	2008-11-03 00:34:05 +0000
@@ -367,10 +367,10 @@ void SerialLogFile::zap()
 	// The error is supposedly related to the file size being less than 
 	// page size, so initial size is made 8K just in case we'll ever run on IA64
 	size_t initialSize = MAX(sectorSize, 8192); 
-	UCHAR *junk = new UCHAR[initialSize +sectorSize];
+	UCHAR *junk = new UCHAR[initialSize + sectorSize];
 	UCHAR *buffer = ALIGN(junk, sectorSize);
-	memset(buffer, 0, sectorSize);
-	write(0, sectorSize, (SerialLogBlock*) buffer);
+	memset(buffer, 0, initialSize);
+	write(0, (uint32) initialSize, (SerialLogBlock*) buffer);
 	delete junk;
 }
 

=== modified file 'storage/falcon/SerialLogRecord.cpp'
--- a/storage/falcon/SerialLogRecord.cpp	2008-04-09 01:36:46 +0000
+++ b/storage/falcon/SerialLogRecord.cpp	2008-11-11 22:33:27 +0000
@@ -100,6 +100,7 @@ int init()
 SerialLogRecord::SerialLogRecord()
 {
 	transactionId = 0;
+	type = 0;
 }
 
 SerialLogRecord::~SerialLogRecord()

=== modified file 'storage/falcon/SerialLogRecord.h'
--- a/storage/falcon/SerialLogRecord.h	2008-02-14 21:06:10 +0000
+++ b/storage/falcon/SerialLogRecord.h	2008-11-11 22:33:27 +0000
@@ -111,6 +111,7 @@ public:
 	SerialLog			*log;
 	SerialLogControl	*control;
 	TransId				transactionId;
+	UCHAR				type;
 };
 
 

=== modified file 'storage/falcon/Serialize.cpp'
--- a/storage/falcon/Serialize.cpp	2008-02-25 22:27:17 +0000
+++ b/storage/falcon/Serialize.cpp	2008-10-31 15:42:42 +0000
@@ -82,7 +82,7 @@ void Serialize::putInt(int value)
 		*p++ = (value >> (lengthShifts [count])) & 0x7f;
 
 	*p++ = value | LOW_BYTE_FLAG;
-	release(p - data);
+	release((uint)(p - data));
 }
 
 void Serialize::putInt64(int64 value)
@@ -95,7 +95,7 @@ void Serialize::putInt64(int64 value)
 		*p++ = (UCHAR) (value >> (lengthShifts [count])) & 0x7f;
 
 	*p++ = ((UCHAR) value) | LOW_BYTE_FLAG;
-	release(p - data);
+	release((uint)(p - data));
 }
 
 void Serialize::putData(uint length, const UCHAR* data)

=== modified file 'storage/falcon/StorageHandler.cpp'
--- a/storage/falcon/StorageHandler.cpp	2008-10-01 03:13:44 +0000
+++ b/storage/falcon/StorageHandler.cpp	2008-11-13 13:27:13 +0000
@@ -36,8 +36,6 @@
 #include "CmdGen.h"
 #include "Dbb.h"
 #include "Database.h"
-#include "TableSpaceManager.h"
-#include "IOx.h"
 
 #define DICTIONARY_ACCOUNT		"mysql"
 #define DICTIONARY_PW			"mysql"
@@ -505,12 +503,6 @@ int StorageHandler::createTablespace(con
 		return StorageErrorTableSpaceExist;
 		}
 
-	TableSpaceManager *tableSpaceManager =
-		dictionaryConnection->database->tableSpaceManager;
-
-	if (!tableSpaceManager->waitForPendingDrop(filename, 10))
-		// file still exists after waiting for 10 seconds
-		return  StorageErrorTableSpaceDataFileExist;
 
 	try
 		{
@@ -1006,6 +998,8 @@ void StorageHandler::initialize(void)
 
 		try
 			{
+			Log::log(LogMysqlInfo, "Falcon: unable to open system data files.");
+			Log::log(LogMysqlInfo, "Falcon: creating new system data files.");
 			createDatabase();
 			}
 		catch(SQLException &e2)

=== modified file 'storage/falcon/StorageTableShare.cpp'
--- a/storage/falcon/StorageTableShare.cpp	2008-10-22 20:44:09 +0000
+++ b/storage/falcon/StorageTableShare.cpp	2008-11-05 14:51:37 +0000
@@ -262,7 +262,7 @@ int StorageTableShare::truncateTable(Sto
 	return res;
 }
 
-const char* StorageTableShare::cleanupFieldName(const char* name, char* buffer, int bufferLength)
+const char* StorageTableShare::cleanupFieldName(const char* name, char* buffer, int bufferLength, bool doubleQuotes)
 {
 	char *q = buffer;
 	char *end = buffer + bufferLength - 1;
@@ -273,7 +273,11 @@ const char* StorageTableShare::cleanupFi
 		{
 		if (*p == '"')
 			{
-			*q++ = UPPER(*p);
+			if (doubleQuotes)
+				{
+				*q++ = UPPER(*p);
+				}
+
 			quotes = !quotes;
 			}
 	
@@ -321,7 +325,7 @@ char* StorageTableShare::createIndexName
 	else
 		{
 		char nameBuffer[indexNameSize];
-		cleanupFieldName(rawName, nameBuffer, sizeof(nameBuffer));
+		cleanupFieldName(rawName, nameBuffer, sizeof(nameBuffer), true);
 		sprintf(indexName, "%s$%s", name.getString(), nameBuffer);
 		}
 	

=== modified file 'storage/falcon/StorageTableShare.h'
--- a/storage/falcon/StorageTableShare.h	2008-10-22 20:44:09 +0000
+++ b/storage/falcon/StorageTableShare.h	2008-11-05 14:51:37 +0000
@@ -123,7 +123,7 @@ public:
 	virtual INT64		getSequenceValue(int delta);
 	virtual int			setSequenceValue(INT64 value);
 	virtual int			haveIndexes(int indexCount);
-	virtual const char*	cleanupFieldName(const char* name, char* buffer, int bufferLength);
+	virtual const char*	cleanupFieldName(const char* name, char* buffer, int bufferLength, bool doubleQuotes);
 	virtual void		setTablePath(const char* path, bool tempTable);
 	virtual void		registerCollation(const char* collationName, void* arg);
 

=== modified file 'storage/falcon/StorageVersion.h'
--- a/storage/falcon/StorageVersion.h	2008-10-24 15:22:59 +0000
+++ b/storage/falcon/StorageVersion.h	2008-11-14 16:02:16 +0000
@@ -14,5 +14,5 @@
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
 
-#define FALCON_VERSION	"T1.3-0"
-#define FALCON_DATE		"24 October, 2008"
+#define FALCON_VERSION	"T1.3-5"
+#define FALCON_DATE		"14 November, 2008"

=== modified file 'storage/falcon/TableSpaceManager.cpp'
--- a/storage/falcon/TableSpaceManager.cpp	2008-09-22 09:24:39 +0000
+++ b/storage/falcon/TableSpaceManager.cpp	2008-11-05 17:58:43 +0000
@@ -58,7 +58,6 @@ TableSpaceManager::TableSpaceManager(Dat
 	memset(nameHash, 0, sizeof(nameHash));
 	memset(idHash, 0, sizeof(nameHash));
 	tableSpaces = NULL;
-	pendingDrops = 0;
 	syncObject.setName("TableSpaceManager::syncObject");
 }
 
@@ -156,7 +155,7 @@ TableSpace* TableSpaceManager::getTableS
 TableSpace* TableSpaceManager::createTableSpace(const char *name, const char *fileName, bool repository, TableSpaceInit *tsInit)
 {
 	Sync syncDDL(&database->syncSysDDL, "TableSpaceManager::createTableSpace");
-	syncDDL.lock(Shared);
+	syncDDL.lock(Exclusive);
 	Sequence *sequence = database->sequenceManager->getSequence(database->getSymbol("SYSTEM"), database->getSymbol("TABLESPACE_IDS"));
 	int type = (repository) ? TABLESPACE_TYPE_REPOSITORY : TABLESPACE_TYPE_TABLESPACE;
 	int id = (int) sequence->update(1, database->getSystemTransaction());
@@ -169,26 +168,26 @@ TableSpace* TableSpaceManager::createTab
 		throw SQLError(TABLESPACE_DATAFILE_EXIST_ERROR, "table space file name \"%s\" already exists\n", fileName);
 		}
 		
+	bool createdFile = false;
 	try
 		{
 		tableSpace->save();
 		
 		if (!repository)
 			tableSpace->create();
-			
-		syncDDL.unlock();
-		database->commitSystemTransaction();
+		createdFile = true;
 		add(tableSpace);
+		database->serialLog->logControl->createTableSpace.append(tableSpace);
 		}
 	catch (...)
 		{
+		if (createdFile)
+			IO::deleteFile(fileName);
+		database->rollbackSystemTransaction();
 		delete tableSpace;
-
 		throw;
 		}
-
-	database->serialLog->logControl->createTableSpace.append(tableSpace);
-	
+	database->commitSystemTransaction();
 	return tableSpace;
 }
 
@@ -298,13 +297,14 @@ void TableSpaceManager::dropTableSpace(T
 			break;
 			}
 			
-	pendingDrops++;
 	syncObj.unlock();
+	tableSpace->active = false;
+	JString filename = tableSpace->dbb->fileName;
 
 	database->serialLog->logControl->dropTableSpace.append(tableSpace, transaction);
 	database->commitSystemTransaction();
+	IO::deleteFile(filename);
 
-	tableSpace->active = false;
 }
 
 void TableSpaceManager::reportStatistics(void)
@@ -370,12 +370,10 @@ void TableSpaceManager::expungeTableSpac
 			}
 
 	sync.unlock();
-	tableSpace->dropTableSpace();
+	//File already deleted, just close the file descriptor
+	tableSpace->close();
 	delete tableSpace;
 
-	sync.lock(Exclusive);
-	if(pendingDrops >0)
-		pendingDrops--;
 }
 
 void TableSpaceManager::reportWrites(void)
@@ -563,28 +561,5 @@ void TableSpaceManager::getTableSpaceFil
 		infoTable->setNull(37);			// EXTRA
 		infoTable->putRecord();
 		}
-}
-
-
-// Wait for specified amount of time for a  file to be deleted.
-// Don't wait if pendingDrops count is 0.
-//
-// The function returns true, if wait was successfull, i.e file does not exist
-//(anymore)
-bool TableSpaceManager::waitForPendingDrop(const char  *filename, int seconds)
-{
-	bool fileExists;
-
-	do
-		{
-		fileExists = IO::doesFileExist(filename);
-		if (fileExists && pendingDrops > 0 && seconds-- > 0)
-			Thread::getThread("TransactionManager::waitForPendingDrop")->sleep(1000);
-		else
-			break;
-		}
-	while(true);
-
-	return !fileExists;
 }
 

=== modified file 'storage/falcon/TableSpaceManager.h'
--- a/storage/falcon/TableSpaceManager.h	2008-09-22 09:24:39 +0000
+++ b/storage/falcon/TableSpaceManager.h	2008-10-31 00:29:13 +0000
@@ -63,7 +63,6 @@ public:
 	void			reportWrites(void);
 	void			redoCreateTableSpace(int id, int nameLength, const char* name, int fileNameLength, const char* fileName, int type, TableSpaceInit* tsInit);
 	void			initialize(void);
-	bool			waitForPendingDrop(const char *filename, int seconds);
 
 	Database	*database;
 	TableSpace	*tableSpaces;
@@ -71,7 +70,6 @@ public:
 	TableSpace	*idHash[TS_HASH_SIZE];
 	SyncObject	syncObject;
 	void postRecovery(void);
-	int pendingDrops;
 };
 
 #endif // !defined(AFX_TABLESPACEMANAGER_H__BD1D39F6_2201_4136_899C_7CB106E99B8C__INCLUDED_)

=== modified file 'storage/falcon/Transaction.cpp'
--- a/storage/falcon/Transaction.cpp	2008-10-24 05:06:52 +0000
+++ b/storage/falcon/Transaction.cpp	2008-11-07 01:09:04 +0000
@@ -250,7 +250,8 @@ void Transaction::commit()
 
 	TransactionManager *transactionManager = database->transactionManager;
 	addRef();
-	Log::log(LogXARecovery, "%d: Commit transaction %d\n", database->deltaTime, transactionId);
+	Log::log(LogXARecovery, "%d: Commit %sTransaction %d\n", 
+		database->deltaTime, (systemTransaction ? "System " : ""),  transactionId);
 
 	if (state == Active)
 		{
@@ -340,6 +341,7 @@ void Transaction::commitNoUpdates(void)
 	TransactionManager *transactionManager = database->transactionManager;
 	addRef();
 	ASSERT(!deferredIndexes);
+	Log::log(LogXARecovery, "%d: CommitNoUpdates transaction %d\n", database->deltaTime, transactionId);
 	++transactionManager->committed;
 	
 	if (deferredIndexes)
@@ -384,6 +386,8 @@ void Transaction::rollback()
 	if (!isActive())
 		throw SQLEXCEPTION (RUNTIME_ERROR, "transaction is not active");
 
+	Log::log(LogXARecovery, "%d: Rollback transaction %d\n", database->deltaTime, transactionId);
+
 	if (deferredIndexes)
 		releaseDeferredIndexes();
 		
@@ -534,8 +538,19 @@ void Transaction::chillRecords()
 		
 	uint32 chilledBefore = chilledRecords;
 	uint64 totalDataBefore = totalRecordData;
+	
 	database->dbb->logUpdatedRecords(this, *chillPoint, true);
 	
+	// At the start of a chill operation, all savepoints are updated with the id of the
+	// savepoint being chilled. This ensures that each savepoint in a transaction always
+	// has a bitmap of savepoints that were chilled after it.
+
+	// When a savepoint is rolled back, those newer savepoints for which records have also
+	// been chilled are recorded in the serial log.
+
+	// The idea is that if savepoint N is rolled back, then chilled records attached to
+	// savepoints >= N	are ignored and not committed to the database.
+	
 	for (SavePoint *savePoint = savePoints; savePoint; savePoint = savePoint->next)
 		if (savePoint->id != curSavePointId)
 			savePoint->setIncludedSavepoint(curSavePointId);
@@ -951,6 +966,9 @@ void Transaction::writeComplete(void)
 	if (dependencies == 0)
 		commitRecords();
 
+//	Log::log(LogXARecovery, "%d: WriteComplete %sTransaction %d\n", 
+// 	database->deltaTime, (systemTransaction ? "System " : ""),  transactionId);
+
 	writePending = false;
 }
 
@@ -1093,6 +1111,8 @@ int Transaction::createSavepoint()
 	else
 		savePoint = new SavePoint;
 	
+	// The savepoint begins with the next record added to the transaction
+	
 	savePoint->records = (lastRecord) ? &lastRecord->nextInTrans : &firstRecord;
 	savePoint->id = ++curSavePointId;
 	savePoint->next = savePoints;
@@ -1117,10 +1137,13 @@ void Transaction::releaseSavepoint(int s
 	for (SavePoint **ptr = &savePoints, *savePoint; (savePoint = *ptr); ptr = &savePoint->next)
 		if (savePoint->id == savePointId)
 			{
+			
+			// Savepoints are linked in descending order, so the next lower id is next on the list
+			
 			int nextLowerSavePointId = (savePoint->next) ? savePoint->next->id : 0;
 			*ptr = savePoint->next;
 			
-			// If we have backed logged records, merge them in to the previous savepoint or the transaction itself.
+			// If we have backed logged records, merge them in to the previous savepoint or the transaction itself
 			
 			if (savePoint->backloggedRecords)
 				{
@@ -1148,7 +1171,8 @@ void Transaction::releaseSavepoint(int s
 			if (savePoint->savepoints)
 				savePoint->clear();
 
-			// commit pending record versions to the next pending savepoint
+			// This savepoint is no longer needed, so commit pending record versions to the next pending savepoint
+			// Scavenge prior record versions having 1) the same transaction and 2) savepoint >= the savepoint being released
 			
 			for (RecordVersion *record = *savePoint->records; record && record->savePointId == savePointId; record = record->nextInTrans)
 				{
@@ -1218,12 +1242,19 @@ void Transaction::rollbackSavepoint(int 
 	if ((savePoint) && (savePoint->id != savePointId))
 		throw SQLError(RUNTIME_ERROR, "invalid savepoint");
 
+	// Records within this savepoint or later may have been chilled and are
+	// already in the serial log, but they are now obsolete. To ensure that those
+	// records are not committed to the database, append the serial log with a SRLSavepointRollback
+	// record for this savepoint and for any greater savepoint that has been chilled.
+	
 	if (chilledRecords)
 		{
 		database->serialLog->logControl->savepointRollback.append(transactionId, savePointId);
 		
+		// SavePoint::savepoints is a bitmap of other savepoints that have been chilled
+		
 		if (savePoint->savepoints)
-			for (int n = 0; (n = savePoint->savepoints->nextSet(n)) >= 0; ++n)
+			for (int n = savePointId; (n = savePoint->savepoints->nextSet(n)) >= savePointId; ++n)
 				database->serialLog->logControl->savepointRollback.append(transactionId, n);
 		}				
 
@@ -1285,10 +1316,9 @@ void Transaction::rollbackSavepoint(int 
 		if (savePoint->backloggedRecords)
 			database->backLog->rollbackRecords(savePoint->backloggedRecords, this);
 				
-		// Move skipped savepoints object to the free list
-		// Leave the target savepoint empty, but connected to the transaction.
+		// Move skipped savepoint objects to the free list
 		
-		if (savePoint->id > savePointId)
+		if (savePoint->id >= savePointId)
 			{
 			savePoints = savePoint->next;
 			savePoint->next = freeSavePoints;

=== modified file 'storage/falcon/ha_falcon.cpp'
--- a/storage/falcon/ha_falcon.cpp	2008-10-26 08:45:22 +0000
+++ b/storage/falcon/ha_falcon.cpp	2008-11-13 13:27:13 +0000
@@ -35,6 +35,7 @@
 #include "InfoTable.h"
 #include "Format.h"
 #include "Error.h"
+#include "Log.h"
 
 #ifdef _WIN32
 #define I64FORMAT			"%I64d"
@@ -227,7 +228,9 @@ int StorageInterface::falcon_init(void *
 	falcon_hton->fill_is_table = StorageInterface::fill_is_table;
 	//falcon_hton->show_status  = StorageInterface::show_status;
 	falcon_hton->flags = HTON_NO_FLAGS;
+	falcon_debug_mask&= ~(LogMysqlInfo|LogMysqlWarning|LogMysqlError);
 	storageHandler->addNfsLogger(falcon_debug_mask, StorageInterface::logger, NULL);
+	storageHandler->addNfsLogger(LogMysqlInfo|LogMysqlWarning|LogMysqlError, StorageInterface::mysqlLogger, NULL);
 
 	if (falcon_debug_server)
 		storageHandler->startNfsServer();
@@ -344,7 +347,7 @@ uint falcon_strnxfrmlen(void *cs, const 
 	uint chrLen = falcon_strnchrlen(cs, s, srcLen);
 	int maxChrLen = partialKey ? min(chrLen, partialKey / charset->mbmaxlen) : chrLen;
 
-	return min(charset->coll->strnxfrmlen(charset, maxChrLen * charset->mbmaxlen), (uint) bufSize);
+	return (uint)min(charset->coll->strnxfrmlen(charset, maxChrLen * charset->mbmaxlen), (uint) bufSize);
 }
 
 // Return the number of bytes used in s to hold a certain number of characters.
@@ -372,7 +375,7 @@ uint falcon_strntrunc(void *cs, int part
 		charLimit--;
 		}
 
-	return ch - (uchar *) s;
+	return (uint)(ch - (uchar *) s);
 }
 
 int falcon_strnncoll(void *cs, const char *s1, uint l1, const char *s2, uint l2, char flag)
@@ -536,6 +539,10 @@ int StorageInterface::open(const char *n
 
 	int ret = storageTable->open();
 
+	if (ret == StorageErrorTableNotFound)
+		sql_print_error("Server is attempting to access a table %s,\n"
+				"which doesn't exist in Falcon.", name);
+
 	if (ret)
 		DBUG_RETURN(error(ret));
 
@@ -1025,6 +1032,10 @@ int StorageInterface::delete_table(const
 	storageTable->deleteStorageTable();
 	storageTable = NULL;
 
+	if (res == StorageErrorTableNotFound)
+		sql_print_error("Server is attempting to drop a table %s,\n"
+				"which doesn't exist in Falcon.", tableName);
+
 	// (hk) Fix for Bug#31465 Running Falcon test suite leads
 	//                        to warnings about temp tables
 	// This fix could affect other DROP TABLE scenarios.
@@ -1561,7 +1572,7 @@ int StorageInterface::rename_table(const
 	ret = storageShare->renameTable(storageConnection, to);
 	
 	if (!ret)
-	remapIndexes(table);
+		remapIndexes(table);
 	
 	storageShare->unlock();
 	storageShare->unlockIndexes();
@@ -1805,6 +1816,10 @@ int StorageInterface::error(int storageE
 			                    "Falcon does not support READ UNCOMMITTED ISOLATION, using REPEATABLE READ instead.");
 			break;
 
+		case StorageErrorIndexOverflow:
+			my_error(ER_TOO_LONG_KEY, MYF(0), max_key_length());
+			break;
+
 		default:
 			;
 		}
@@ -2397,6 +2412,16 @@ void StorageInterface::logger(int mask, 
 		}
 }
 
+void StorageInterface::mysqlLogger(int mask, const char* text, void* arg)
+{
+	if (mask & LogMysqlError)
+		sql_print_error("%s", text);
+	else if (mask & LogMysqlWarning)
+		sql_print_warning("%s", text);
+	else if (mask & LogMysqlInfo)
+		sql_print_information("%s", text);
+}
+
 int StorageInterface::setIndex(TABLE *table, int indexId)
 {
 	StorageIndexDesc indexDesc;
@@ -2482,7 +2507,7 @@ int StorageInterface::genTable(TABLE* ta
 		if (charset)
 			storageShare->registerCollation(charset->name, charset);
 
-		storageShare->cleanupFieldName(field->field_name, nameBuffer, sizeof(nameBuffer));
+		storageShare->cleanupFieldName(field->field_name, nameBuffer, sizeof(nameBuffer), true);
 		gen->gen("%s  \"%s\" ", sep, nameBuffer);
 		int ret = genType(field, gen);
 
@@ -2628,7 +2653,7 @@ void StorageInterface::genKeyFields(KEY*
 		{
 		KEY_PART_INFO *part = key->key_part + n;
 		Field *field = part->field;
-		storageShare->cleanupFieldName(field->field_name, nameBuffer, sizeof(nameBuffer));
+		storageShare->cleanupFieldName(field->field_name, nameBuffer, sizeof(nameBuffer), true);
 
 		if (part->key_part_flag & HA_PART_KEY_SEG)
 			gen->gen("%s\"%s\"(%d)", sep, nameBuffer, part->length);
@@ -3006,10 +3031,10 @@ bool StorageInterface::get_error_message
 	if (storageConnection)
 		{
 		const char *text = storageConnection->getLastErrorString();
-		buf->set(text, strlen(text), system_charset_info);
+		buf->set(text, (uint32)strlen(text), system_charset_info);
 		}
 	else if (errorText)
-		buf->set(errorText, strlen(errorText), system_charset_info);
+		buf->set(errorText, (uint32)strlen(errorText), system_charset_info);
 
 	return false;
 }
@@ -3516,6 +3541,7 @@ void StorageInterface::updateRecordScave
 void StorageInterface::updateDebugMask(MYSQL_THD thd, struct st_mysql_sys_var* variable, void* var_ptr, const void* save)
 {
 	falcon_debug_mask = *(uint*) save;
+	falcon_debug_mask&= ~(LogMysqlInfo|LogMysqlWarning|LogMysqlError);
 	storageHandler->deleteNfsLogger(StorageInterface::logger, NULL);
 	storageHandler->addNfsLogger(falcon_debug_mask, StorageInterface::logger, NULL);
 }
@@ -3553,7 +3579,7 @@ void StorageInterface::mapFields(TABLE *
 	for (uint n = 0; n < table->s->fields; ++n)
 		{
 		Field *field = table->field[n];
-		storageShare->cleanupFieldName(field->field_name, nameBuffer, sizeof(nameBuffer));
+		storageShare->cleanupFieldName(field->field_name, nameBuffer, sizeof(nameBuffer), false);
 		int id = storageShare->getFieldId(nameBuffer);
 		
 		if (id >= 0)

=== modified file 'storage/falcon/ha_falcon.h'
--- a/storage/falcon/ha_falcon.h	2008-10-22 20:44:09 +0000
+++ b/storage/falcon/ha_falcon.h	2008-11-13 13:27:13 +0000
@@ -150,6 +150,7 @@ public:
 	static void		shutdown(handlerton *);
 	static int		closeConnection(handlerton *, THD *thd);
 	static void		logger(int mask, const char *text, void *arg);
+	static void		mysqlLogger(int mask, const char *text, void *arg);
 	static int		panic(handlerton* hton, ha_panic_function flag);
 	//static bool	show_status(handlerton* hton, THD* thd, stat_print_fn* print, enum ha_stat_type stat);
 	static int		getMySqlError(int storageError);

=== modified file 'storage/falcon/plug.in'
--- a/storage/falcon/plug.in	2008-09-23 09:08:59 +0000
+++ b/storage/falcon/plug.in	2008-11-03 08:56:28 +0000
@@ -4,6 +4,9 @@ MYSQL_PLUGIN_DIRECTORY(falcon, [storage/
 MYSQL_PLUGIN_STATIC(falcon,    [libfalcon.a])
 MYSQL_PLUGIN_DYNAMIC(falcon,   [ha_falcon.la])
 
+# Check if we have the atomic_* functions on Solaris
+AC_CHECK_FUNC(atomic_cas_32, AC_DEFINE([HAVE_SOLARIS_ATOMIC], [1], [Define to 1 if Solaris support atomic functions.]))
+
 # Check for supported machine types.
 AC_CACHE_CHECK([if Falcon Storage Engine is supported on $MACHINE_TYPE],
   			   falcon_supported_by_machine,[

Thread
bzr commit into mysql-6.0-runtime branch (alik:2765) Alexander Nozdrin5 Dec