2743 Ingo Struewing 2008-11-22 [merge]
merge
modified:
sql/mysqld.cc
sql/nt_servc.cc
sql/nt_servc.h
=== modified file '.bzr-mysql/default.conf'
--- a/.bzr-mysql/default.conf 2008-11-06 18:39:27 +0000
+++ b/.bzr-mysql/default.conf 2008-11-14 15:02:10 +0000
@@ -1,5 +1,5 @@
[MYSQL]
-tree_location = bzr+ssh://bk-internal.mysql.com/bzrroot/server/mysql-6.0
+tree_location = bzr+ssh://bk-internal.mysql.com/bzrroot/server/mysql-6.0-backup
post_commit_to = commits@stripped
post_push_to = commits@stripped
-tree_name = mysql-6.0
+tree_name = mysql-6.0-backup
=== 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 */
=== 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-11-18 21:17:04 +0000
+++ b/mysql-test/mysql-test-run.pl 2008-11-21 15:14:47 +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/suite/backup/r/backup.result'
--- a/mysql-test/suite/backup/r/backup.result 2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup.result 2008-11-17 09:57:51 +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-11-20 07:57:58 +0000
+++ b/mysql-test/suite/backup/r/backup_backupdir.result 2008-11-21 15:14:47 +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-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_db_grants.result 2008-11-17 09:57:51 +0000
@@ -64,7 +64,7 @@ SHOW GRANTS FOR 'bup_user3'@'%';
Grants for bup_user3@%
GRANT USAGE ON *.* TO 'bup_user3'@'%'
Run Restore
-RESTORE FROM 'bup_db_grants.bak';
+RESTORE FROM 'bup_db_grants.bak' OVERWRITE;
backup_id
#
SHOW TABLES FROM bup_db_grants;
@@ -96,7 +96,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
#
SHOW TABLES FROM bup_db_grants;
@@ -166,7 +166,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_errors.result'
--- a/mysql-test/suite/backup/r/backup_errors.result 2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_errors.result 2008-11-17 09:57:51 +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-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_lock_myisam.result 2008-11-17 09:57:51 +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';
@@ -92,7 +92,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';
=== 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_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-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_db_grants.test 2008-11-17 09:57:51 +0000
@@ -63,7 +63,7 @@ SHOW GRANTS FOR 'bup_user3'@'%';
--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;
@@ -90,7 +90,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;
@@ -178,7 +178,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_errors.test'
--- a/mysql-test/suite/backup/t/backup_errors.test 2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_errors.test 2008-11-17 09:57:51 +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';
@@ -238,6 +255,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
=== 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,85 +96,146 @@ 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
@@ -164,3 +243,5 @@ DROP DATABASE bup_nodata;
--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-10-30 10:41:48 +0000
@@ -11,6 +11,6 @@
##############################################################################
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
=== 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/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
+
=== modified file 'sql/backup/backup_info.cc'
--- a/sql/backup/backup_info.cc 2008-10-27 13:06:21 +0000
+++ b/sql/backup/backup_info.cc 2008-11-05 09:41:15 +0000
@@ -543,6 +543,10 @@ int Backup_info::add_dbs(List< ::LEX_STR
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-10-27 13:06:21 +0000
+++ b/sql/backup/backup_info.h 2008-11-13 13:02:36 +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. */
@@ -134,6 +138,12 @@ class Backup_restore_ctx: public backup:
*/
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);
@@ -627,6 +651,13 @@ int write_table_data(THD* thd, Backup_in
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-10-15 15:38:28 +0000
+++ b/sql/backup/image_info.h 2008-11-05 09:41:15 +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-11-06 18:39:27 +0000
+++ b/sql/backup/kernel.cc 2008-11-17 09:57:51 +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;
@@ -211,6 +213,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);
@@ -219,7 +228,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");
@@ -324,7 +333,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:
@@ -378,7 +386,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.
@@ -391,7 +400,7 @@ Backup_restore_ctx::Backup_restore_ctx(T
Backup_restore_ctx::~Backup_restore_ctx()
{
close();
-
+
delete mem_alloc;
delete m_catalog;
delete m_stream;
@@ -785,6 +794,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;
}
@@ -838,11 +866,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;
@@ -923,6 +958,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
@@ -1154,11 +1200,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");
@@ -1178,6 +1227,23 @@ 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(&mydb->name())) {
+ DBUG_RETURN(fatal_error(ER_RESTORE_DB_EXISTS, mydb->name().ptr()));
+ }
+ }
+ delete dbit;
+ }
+
disable_fkey_constraints(); // Never errors
if (read_meta_data(info, s))
@@ -1253,6 +1319,8 @@ int Backup_restore_ctx::do_restore()
report_stats_post(info); // Never errors
+ DEBUG_SYNC(m_thd, "before_restore_done");
+
DBUG_RETURN(0);
}
@@ -1924,6 +1992,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.
@@ -271,6 +280,22 @@ void Logger::report_binlog_pos(const st_
}
/**
+ 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();
+ }
+}
+
+/**
Report driver.
*/
inline
=== 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,10 +1277,9 @@ 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-11-06 18:39:27 +0000
+++ b/sql/log.cc 2008-11-13 08:40:43 +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>
@@ -778,10 +779,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;
@@ -856,6 +865,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();
@@ -951,6 +965,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;
}
@@ -1096,6 +1116,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)
{
@@ -1256,12 +1592,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();
@@ -1411,6 +1790,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
@@ -1651,6 +2115,7 @@ bool LOGGER::backup_progress_log_write(T
else
id= 0; /* Log from connect handler */
+
lock_shared();
while (*current_handler)
error|= (*current_handler++)->
@@ -3605,7 +4070,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-11-06 18:46:03 +0000
+++ b/sql/log_event.cc 2008-11-14 13:24:32 +0000
@@ -9144,13 +9144,12 @@ 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-11-22 00:12:37 +0000
+++ b/sql/mysqld.cc 2008-11-22 15:46:20 +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},
@@ -5854,7 +5856,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
};
@@ -6122,6 +6126,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 "
@@ -8275,7 +8289,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-20 12:55:24 +0000
+++ b/sql/set_var.cc 2008-11-21 15:14:47 +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;
@@ -553,6 +553,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);
@@ -2399,7 +2401,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);
}
@@ -2562,7 +2572,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-20 12:55:24 +0000
+++ b/sql/share/errmsg.txt 2008-11-21 15:14:47 +0000
@@ -6419,7 +6419,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);
@@ -192,4 +205,20 @@ void Backup_log::binlog_file(char *file)
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-10-27 13:06:21 +0000
+++ b/sql/si_objects.cc 2008-10-30 12:29:54 +0000
@@ -25,11 +25,15 @@
#include "sql_trigger.h"
#include "sp.h"
#include "sp_head.h" // for sp_add_to_query_tables().
+#include "rpl_mi.h"
TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list); // defined in sql_show.cc
DDL_blocker_class *DDL_blocker= NULL;
+extern HASH slave_list;
+extern my_bool disable_slaves;
+
///////////////////////////////////////////////////////////////////////////
namespace {
@@ -459,6 +463,36 @@ COND *create_db_select_condition(THD *th
///////////////////////////////////////////////////////////////////////////
/**
+ @class ProcessObj
+
+ This class provides an abstraction to a process object for reading
+ items from the process list.
+*/
+class ProcessObj : public Obj
+{
+public:
+ ProcessObj(const String *proc_name) { m_command.copy(*proc_name); };
+
+public:
+ bool materialize(uint serialization_version,
+ const String *serialization)
+ { return FALSE; }
+
+ const String* get_name()
+ { return &m_command; }
+
+ const String *get_db_name() { return NULL; }
+
+private:
+ // These attributes are to be used only for serialization.
+ String m_command;
+
+ bool drop(THD *thd) { return FALSE; }
+ bool do_serialize(THD *thd, String *serialization) { return FALSE; }
+ bool do_execute(THD *thd) { return FALSE; }
+};
+
+/**
@class DatabaseObj
This class provides an abstraction to a database object for creation and
@@ -945,6 +979,22 @@ protected:
};
///////////////////////////////////////////////////////////////////////////
+class ProcesslistIterator : public InformationSchemaIterator
+{
+public:
+ ProcesslistIterator(THD *thd,
+ TABLE *is_table,
+ handler *ha,
+ my_bitmap_map *orig_columns) :
+ InformationSchemaIterator(thd, is_table, ha, orig_columns)
+ { }
+
+protected:
+ virtual ProcessObj *create_obj(TABLE *t);
+};
+
+
+///////////////////////////////////////////////////////////////////////////
class DatabaseIterator : public InformationSchemaIterator
{
public:
@@ -1272,6 +1322,25 @@ Obj *InformationSchemaIterator::next()
///////////////////////////////////////////////////////////////////////////
//
+// Implementation: ProcesslistIterator class.
+//
+
+///////////////////////////////////////////////////////////////////////////
+
+ProcessObj* ProcesslistIterator::create_obj(TABLE *t)
+{
+ String name;
+
+ t->field[4]->val_str(&name);
+
+ DBUG_PRINT("ProcesslistIterator::create_obj", (" Found process %s", name.ptr()));
+
+ return new ProcessObj(&name);
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+//
// Implementation: DatabaseIterator class.
//
@@ -2126,8 +2195,15 @@ bool TableObj::do_serialize(THD *thd, St
/*
Open the view and its base tables or views
- */
- if (open_normal_and_derived_tables(thd, table_list, 0)) {
+
+ The MYSQL_OPEN_SKIP_TEMPORARY flag is needed because TableObj always
+ refers to a regular table, even if a temporary table with the same name
+ exists in the database (see BUG#33574).
+ */
+ if (open_normal_and_derived_tables(thd, table_list,
+ MYSQL_OPEN_SKIP_TEMPORARY)
+ )
+ {
close_thread_tables(thd);
thd->lex->select_lex.table_list.empty();
DBUG_RETURN(TRUE);
@@ -3861,6 +3937,199 @@ int Name_locker::release_name_locks()
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()
+{
+ int num_slaves= 0;
+ TABLE *is_table;
+ handler *ha;
+ my_bitmap_map *orig_columns;
+ ProcesslistIterator *pl= 0;
+ Obj *proc= 0;
+ THD *thd= current_thd;
+
+ if (InformationSchemaIterator::prepare_is_table(
+ thd, &is_table, &ha, &orig_columns, SCH_PROCESSLIST,
+ thd->lex->db_list))
+ goto err;
+
+ pl= new ProcesslistIterator(thd, is_table, ha, orig_columns);
+
+ if (pl)
+ {
+ while ((proc= pl->next()))
+ {
+ const String *p= proc->get_name();
+ if (my_strcasecmp(system_charset_info, p->ptr(),
+ "Binlog Dump") == 0)
+ num_slaves++;
+ }
+ }
+err:
+ return num_slaves;
+}
+
+/**
+ 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;
+}
+
} // obs namespace
///////////////////////////////////////////////////////////////////////////
=== modified file 'sql/si_objects.h'
--- a/sql/si_objects.h 2008-10-27 13:06:21 +0000
+++ b/sql/si_objects.h 2008-10-28 18:14:14 +0000
@@ -708,6 +708,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-10-16 02:13:16 +0000
+++ b/sql/sql_lex.cc 2008-11-13 08:40:43 +0000
@@ -3027,3 +3027,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-04 11:30:00 +0000
+++ b/sql/sql_lex.h 2008-11-13 08:40:43 +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
@@ -1526,6 +1526,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;
@@ -1872,6 +1873,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-11-06 18:39:27 +0000
+++ b/sql/sql_parse.cc 2008-11-17 09:57:51 +0000
@@ -43,7 +43,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) \
@@ -2124,6 +2124,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:
{
@@ -2224,11 +2312,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
@@ -471,6 +472,17 @@ void mysql_binlog_send(THD* thd, char* l
}
#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())
{
errmsg = "Binary log is not open";
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2008-11-06 18:39:27 +0000
+++ b/sql/sql_yacc.yy 2008-11-17 09:57:51 +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 {
| Thread |
|---|
| • bzr push into mysql-6.0-backup branch (ingo.struewing:2743) | Ingo Struewing | 22 Nov |