List:Commits« Previous MessageNext Message »
From:Chuck Bell Date:February 9 2009 10:24pm
Subject:bzr commit into mysql-6.0-backup branch (charles.bell:2764) Bug#39780
View as plain text  
#At file:///C:/source/bzr/mysql-6.0-bug-39780/ based on revid:charles.bell@stripped

 2764 Chuck Bell	2009-02-09
      BUG#39780 Allow restore to skip gap event during restore on master 
      
      This patch adds a new option to the restore command: skip_gap_event.
      It is used to skip writing the incident event when a restore is
      run on a master in an active replication topology (gap event).
modified:
  mysql-test/suite/rpl/r/rpl_backup.result
  mysql-test/suite/rpl/t/rpl_backup.test
  sql/backup/backup_kernel.h
  sql/backup/kernel.cc
  sql/lex.h
  sql/sql_parse.cc
  sql/sql_yacc.yy

per-file messages:
  mysql-test/suite/rpl/r/rpl_backup.result
    Corrected result file.
  mysql-test/suite/rpl/t/rpl_backup.test
    Added test case for skipping gap event.
    Minor refactoring of comments.
  sql/backup/backup_kernel.h
    Added parameter to pass on value of skip_gap_event check.
  sql/backup/kernel.cc
    Added parameter to pass on the result of the skip_gap_event check.
    Added code to skip gap event when triggered.
  sql/lex.h
    Added new symbol.
  sql/sql_parse.cc
    Added code to pass the skip_gap_event signal to the proper locations.
    Simplified option check code.
  sql/sql_yacc.yy
    Extended restore syntax to include new option.
=== modified file 'mysql-test/suite/rpl/r/rpl_backup.result'
--- a/mysql-test/suite/rpl/r/rpl_backup.result	2009-02-01 19:17:09 +0000
+++ b/mysql-test/suite/rpl/r/rpl_backup.result	2009-02-09 22:23:14 +0000
@@ -4,45 +4,49 @@ reset master;
 reset slave;
 drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
 start slave;
-Create some data...
+# Connecting to master...
+# 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.
+# Remove all entries in the backup logs.
 FLUSH BACKUP LOGS;
 PURGE BACKUP LOGS;
-Get slave's datadir.
-Remove all entries in the backup logs.
+# Connecting to slave...
+# Get slave's datadir.
+# 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 datadir.
-Get master's binlog position before backup.
+# Get master's binlog position from the slave before backup.
+# Connecting to master...
+# Get master's datadir.
+# Get master's binlog position before backup.
 SET SESSION debug="+d,set_backup_id";
-Backup_id = 500.
+# 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!
+# 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.
+# 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.
+# Connecting to slave...
+# 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.
+# 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;
@@ -86,22 +90,26 @@ Last_SQL_Errno	0
 Last_SQL_Error	
 Replicate_Ignore_Server_Ids	
 Master_Server_Id	1
-Ensure replication is still working...
-Cleanup from last error on master and slave.
+# Connecting to master...
+# 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
+# Connecting to slave...
 SELECT count(*) FROM rpl_backup.t1;
 count(*)
 3
-Cleanup backup logs.
+# Cleanup backup logs.
 FLUSH BACKUP LOGS;
 PURGE BACKUP LOGS;
-First, get master's binlog position and filename.
+# Connecting to master...
+# First, get master's binlog position and filename.
+# Connecting to slave...
 SET SESSION debug="+d,set_backup_id";
-Backup_id = 600.
+# Backup_id = 600.
 BACKUP DATABASE rpl_backup TO 'rpl_bup_s1.bak';
 backup_id
 600
@@ -147,50 +155,54 @@ Last_SQL_Errno	0
 Last_SQL_Error	
 Replicate_Ignore_Server_Ids	
 Master_Server_Id	1
-Check saving of master's binlog information.
-Should have count(*) = 1.
+# Check saving of master's binlog information.
+# Should have count(*) = 1.
 count(*)
 1
-Should have count(*) = 1.
+# Should have count(*) = 1.
 SELECT count(*) FROM mysql.backup_history;
 count(*)
 1
+# Connecting to master...
 INSERT INTO rpl_backup.t1 VALUES (10), (20), (30);
-Backup_id = 501.
-BACKUP DATABASE rpl_backup TO 'rpl_bup_m2.bak';
+# Backup_id = 501.
+# BACKUP DATABASE rpl_backup TO 'rpl_bup_m2.bak';
 backup_id
 501
 SELECT count(*) FROM rpl_backup.t1;
 count(*)
 6
+# Connecting to slave...
 SELECT count(*) FROM rpl_backup.t1;
 count(*)
 6
-Make a backup for later use.
-Backup_id = 601.
+# Make a backup for later use.
+# Backup_id = 601.
 BACKUP DATABASE rpl_backup TO 'rpl_bup_s2.bak';
 backup_id
 601
+# Connecting to master...
 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';
+# Get master's binlog position before restore.
+# Backup_id = 502.
+# RESTORE FROM 'rpl_bup_m2.bak';
 backup_id
 502
-Show the incident event issued as a result of 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
-Showing tables on master.
+# 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.
+# Connecting to slave...
+# Check slave got everything up to incident event.
+# Should be two rows: 888, 999.
 SELECT * FROM rpl_backup.t2 WHERE b > 800;
 b
 888
@@ -236,23 +248,23 @@ 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.
 Replicate_Ignore_Server_Ids	
 Master_Server_Id	1
-Show the slave stopped with an error.
+# 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.
+# 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 'rpl_bup_m2.bak';
+# Backup_id = 602.
+# RESTORE_FROM 'rpl_bup_m2.bak';
 backup_id
 602
-Showing databases on slave.
+# Showing databases on slave.
 SHOW DATABASES LIKE 'rpl_backup%';
 Database (rpl_backup%)
 rpl_backup
@@ -260,21 +272,23 @@ SELECT count(*) FROM rpl_backup.t1;
 count(*)
 6
 START SLAVE;
-Make a backup for later use.
-Backup_id = 603.
+# 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.
+# Connecting to slave...
+# 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 and restart after restore.
 STOP SLAVE;
 RESTORE FROM 'rpl_bup_s3.bak' OVERWRITE;
 backup_id
 #
 START SLAVE;
-Checking affect on replication.
+# Connecting to master...
+# Checking affect on replication.
 INSERT INTO rpl_backup.t1 VALUES (44), (55), (66);
 SELECT * FROM rpl_backup.t1 ORDER BY a;
 a
@@ -287,6 +301,7 @@ a
 44
 55
 66
+# Connecting to slave...
 SELECT * FROM rpl_backup.t1 ORDER BY a;
 a
 10
@@ -298,50 +313,55 @@ a
 44
 55
 66
-Stop replication and turn off binary log.
+# Connecting to slave...
+# Stop replication and turn off binary log.
 STOP SLAVE;
+# Connecting to master...
 SET @orig_sql_log_bin= @@sql_log_bin;
-Turn off binlog.
+# 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_id = 503.
 BACKUP DATABASE rpl_backup TO 'rpl_bup_m3.bak';
 backup_id
 503
-Turn on binlog;
+# 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.
+# 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.
+# 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.
+# 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
 RESET MASTER;
+# Connecting to slave...
 RESET SLAVE;
 SET DEBUG_SYNC = 'reset';
+# Connecting to slave...
 SET DEBUG_SYNC = 'before_restore_done SIGNAL restore_running WAIT_FOR proceed';
 RESTORE FROM 'rpl_bup_s3.bak' OVERWRITE;
+# Connecting to slave...
 SET DEBUG_SYNC = 'now WAIT_FOR restore_running';
-Try to start the slave while restore is running -- gets error.
+# Try to start the slave while restore is running -- gets error.
 SLAVE START;
 ERROR HY000: Cannot start slave. SLAVE START is blocked by RESTORE.
 SET DEBUG_SYNC = 'now SIGNAL proceed';
@@ -386,10 +406,12 @@ Last_SQL_Errno	0
 Last_SQL_Error	
 Replicate_Ignore_Server_Ids	
 Master_Server_Id	1
-Restore is now complete.
+# Connecting to slave...
+# Restore is now complete.
 backup_id
 #
 SET DEBUG_SYNC = 'now SIGNAL done';
+# Connecting to slave...
 SET DEBUG_SYNC = 'now WAIT_FOR done';
 SHOW DATABASES;
 Database
@@ -399,7 +421,7 @@ mysql
 rpl_backup
 test
 SET DEBUG_SYNC = 'reset';
-Try to start the slave after restore is done -- should succeed.
+# Try to start the slave after restore is done -- should succeed.
 SLAVE START;
 SHOW SLAVE STATUS;
 Slave_IO_State	#
@@ -442,11 +464,67 @@ Last_SQL_Errno	0
 Last_SQL_Error	
 Replicate_Ignore_Server_Ids	
 Master_Server_Id	1
-Now stop the slave.
+# Now stop the slave.
 SLAVE STOP;
+# Connecting to master...
+# First, reset replication. 
+RESET MASTER;
+# Connecting to slave...
+RESET SLAVE;
+SET DEBUG_SYNC = 'reset';
+# Connecting to slave...
+START SLAVE;
+# Connecting to master...
+# Create a new database on the master. 
+CREATE DATABASE not_replicated;
+CREATE TABLE not_replicated.t1 (a int);
+INSERT INTO not_replicated.t1 VALUES (200), (300), (400);
+SHOW DATABASES;
+Database
+information_schema
+mtr
+mysql
+not_replicated
+rpl_backup
+test
+# Connecting to slave...
+# Now let's see if it is replicated on the slave (shouldn't be).
+SHOW DATABASES;
+Database
+information_schema
+mtr
+mysql
+not_replicated
+rpl_backup
+test
+# Connecting to master...
+# Now back to the master to make a backup of the new database.
+# Backup_id = 505.
+BACKUP DATABASE not_replicated TO 'rpl_bup_m4.bak';
+backup_id
+505
+# Now let's run the restore and see if the slave stops.
+# Backup_id = 506.
+RESTORE FROM 'rpl_bup_m4.bak' OVERWRITE SKIP_GAP_EVENT;
+backup_id
+506
+# Let's ensure replication is still running.
+INSERT INTO rpl_backup.t1 VALUES (901), (902), (903);
+# Connecting to slave...
+SELECT * FROM rpl_backup.t1 WHERE a > 900;
+a
+901
+902
+903
+# Now stop the slave.
+SLAVE STOP;
+# Connecting to master...
 FLUSH BACKUP LOGS;
 PURGE BACKUP LOGS;
 DROP DATABASE rpl_backup;
+DROP DATABASE not_replicated;
+# Connecting to slave...
 FLUSH BACKUP LOGS;
 PURGE BACKUP LOGS;
 DROP DATABASE rpl_backup;
+DROP DATABASE not_replicated;

=== modified file 'mysql-test/suite/rpl/t/rpl_backup.test'
--- a/mysql-test/suite/rpl/t/rpl_backup.test	2009-01-29 21:17:59 +0000
+++ b/mysql-test/suite/rpl/t/rpl_backup.test	2009-02-09 22:23:14 +0000
@@ -4,12 +4,12 @@
 
 --source include/master-slave.inc
 --source include/not_embedded.inc
---source include/have_debug_sync.inc
 --source include/have_debug.inc
 
+--echo # Connecting to master...
 connection master;
 
---echo Create some data...
+--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);
@@ -20,30 +20,32 @@ INSERT INTO rpl_backup.t1 VALUES (1), (2
 #   the backup event nor shall the master replicate any data produced
 #   (logged) by the backup. 
 
---echo Remove all entries in the backup logs.
+--echo # Remove all entries in the backup logs.
 FLUSH BACKUP LOGS;
 PURGE BACKUP LOGS;
 
+--echo # Connecting to slave...
 sync_slave_with_master;
 connection slave;
 
---echo Get slave's datadir.
+--echo # Get slave's datadir.
 let $MYSQLD_S_DATADIR= `select @@datadir`;
 
---echo Remove all entries in the backup logs.
+--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.
+--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);
 
+--echo # Connecting to master...
 connection master;
 
---echo Get master's datadir.
+--echo # Get master's datadir.
 let $MYSQLD_M_DATADIR= `select @@datadir`;
 
---echo Get master's binlog position before backup.
+--echo # Get master's binlog position before backup.
 let $master_before_pos = query_get_value("SHOW MASTER STATUS", Position, 1);
 
 #
@@ -55,25 +57,38 @@ SET SESSION debug="+d,set_backup_id";
 replace_regex /(location ').*'/location '$MYSQLD_M_DATADIR\/master_data\/not\/there\/either\/rpl_backup_m1.bak'/ ;
 # 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.
+#
+# NOTICE TO TEST DEVELOPERS:
+#
+# The use of the set_backup_id sets the first backup_id used to 500
+# for a master (or standalone) and 600 for a slave.
+#
+# The backup_id will be incremented by one after that (501, 502, ...)
+# If you change this test by inserting new test cases in the middle
+# of the test, you should also change the echo'ed comments to reflect
+# the renumbered steps.
+#
+--echo # Backup_id = 500.
 BACKUP DATABASE rpl_backup TO 'rpl_bup_m1.bak';
 
+--remove_file $MYSQLD_M_DATADIR/rpl_bup_m1.bak
+
 SET SESSION debug="-d";
 
---echo Show any events issued as a result of backup.
---echo Note: There should be none!
+--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.
+--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.
+--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
 
@@ -82,6 +97,7 @@ eval SELECT $master_after_pos - $master_
 # Check slave's master position.
 # Ensure replication is still working.
 #
+--echo # Connecting to slave...
 sync_slave_with_master;
 connection slave;
 
@@ -89,18 +105,18 @@ 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.
+--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.
+--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.
+--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
 
@@ -108,10 +124,11 @@ eval SELECT $slave_after_pos - $slave_be
 --replace_column 1 # 6 # 7 # 8 # 9 # 22 # 23 # 33 #
 --query_vertical SHOW SLAVE STATUS
 
+--echo # Connecting to master...
 connection master;
 
---echo Ensure replication is still working...
---echo Cleanup from last error on master and slave.
+--echo # Ensure replication is still working...
+--echo # Cleanup from last error on master and slave.
 
 DELETE FROM rpl_backup.t1;
 
@@ -119,12 +136,13 @@ INSERT INTO rpl_backup.t1 VALUES (11), (
 
 SELECT count(*) FROM rpl_backup.t1;
 
+--echo # Connecting to slave...
 sync_slave_with_master;
 connection slave;
 
 SELECT count(*) FROM rpl_backup.t1;
 
---echo Cleanup backup logs.
+--echo # Cleanup backup logs.
 FLUSH BACKUP LOGS;
 PURGE BACKUP LOGS;
 
@@ -135,12 +153,14 @@ PURGE BACKUP LOGS;
 #      the progress log.
 #
 
+--echo # Connecting to master...
 connection master;
 
---echo First, get master's binlog position and filename.
+--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);
 
+--echo # Connecting to slave...
 connection slave;
 
 #
@@ -153,7 +173,7 @@ SET SESSION debug="+d,set_backup_id";
 replace_regex /(location ').*'/location '$MYSQLD_S_DATADIR\/master_data\/not\/there\/either\/rpl_backup_s1.bak'/ ;
 # 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.
+--echo # Backup_id = 600.
 BACKUP DATABASE rpl_backup TO 'rpl_bup_s1.bak';
 
 SET SESSION debug="-d";
@@ -169,17 +189,18 @@ let $preamble = 'Recording master binlog
 let $middle = ''', position = ';
 let $end = '.';
 
---echo Check saving of master's binlog information.
---echo Should have count(*) = 1.
+--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.
+--echo # Should have count(*) = 1.
 SELECT count(*) FROM mysql.backup_history;
 
+--echo # Connecting to master...
 connection master;
 
 #
@@ -188,30 +209,34 @@ connection master;
 
 INSERT INTO rpl_backup.t1 VALUES (10), (20), (30);
 
---echo Backup_id = 501.
+--echo # Backup_id = 501.
 # Must mask command because dir in evaluation of $MYSQL... is not deterministic
---echo BACKUP DATABASE rpl_backup TO 'rpl_bup_m2.bak';
+--echo # BACKUP DATABASE rpl_backup TO 'rpl_bup_m2.bak';
 --disable_query_log
 eval BACKUP DATABASE rpl_backup TO '$MYSQLTEST_VARDIR/rpl_bup_m2.bak';
 --enable_query_log
 
 SELECT count(*) FROM rpl_backup.t1;
 
+--echo # Connecting to slave...
 sync_slave_with_master;
 connection slave;
 
 SELECT count(*) FROM rpl_backup.t1;
 
---echo Make a backup for later use.
+--echo # Make a backup for later use.
 # Must mask command because dir in evaluation of $MYSQL... is not deterministic
 replace_regex /(location ').*'/location '$MYSQLD_S_DATADIR\/master_data\/not\/there\/either\/rpl_backup_s2.bak'/ ;
---echo Backup_id = 601.
+--echo # Backup_id = 601.
 BACKUP DATABASE rpl_backup TO 'rpl_bup_s2.bak';
 
+--remove_file $MYSQLD_S_DATADIR/rpl_bup_s2.bak
+
 #
 #  Use Case 2 - Restore performed on a master.
 #
 
+--echo # Connecting to master...
 connection master;
 
 #
@@ -221,24 +246,24 @@ connection master;
 CREATE TABLE rpl_backup.t2 (b int);
 INSERT INTO rpl_backup.t2 VALUES (888), (999);
 
---echo Get master's binlog position before restore.
+--echo # Get master's binlog position before restore.
 let $master_before_pos = query_get_value("SHOW MASTER STATUS", Position, 1);
 
 # Must mask command because dir in evaluation of $MYSQL... is not deterministic
 replace_regex /(location ').*'/location '$MYSQLTEST_VARDIR\/master_data\/not\/there\/either\/rpl_backup_m2.bak'/ ;
---echo Backup_id = 502.
---echo RESTORE FROM 'rpl_bup_m2.bak';
+--echo # Backup_id = 502.
+--echo # RESTORE FROM 'rpl_bup_m2.bak';
 --disable_query_log
 eval RESTORE FROM '$MYSQLTEST_VARDIR/rpl_bup_m2.bak' OVERWRITE;
 --enable_query_log
 
---echo Show the incident event issued as a result of restore.
+--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.
+--echo # Showing tables on master.
 SHOW FULL TABLES FROM rpl_backup;
 
 SELECT count(*) FROM rpl_backup.t1;
@@ -246,19 +271,20 @@ SELECT count(*) FROM rpl_backup.t1;
 #
 # Wait for slave to stop as result of incident event.
 #
+--echo # Connecting to slave...
 connection slave;
 
 source include/wait_for_slave_sql_to_stop.inc;
 
---echo Check slave got everything up to incident event.
---echo Should be two rows: 888, 999.
+--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.
+--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;
@@ -275,7 +301,7 @@ START SLAVE;
 # Sync with master to ensure nothing is replicated after incident event.
 sync_with_master;
 
---echo Showing tables on slave.
+--echo # Showing tables on slave.
 SHOW FULL TABLES FROM rpl_backup;
 
 #
@@ -288,13 +314,15 @@ STOP SLAVE;
 
 # Must mask command because dir in evaluation of $MYSQL... is not deterministic
 replace_regex /(location ').*'/location '$MYSQLTEST_VARDIR\/master_data\/not\/there\/either\/rpl_backup_m2.bak'/ ;
---echo Backup_id = 602.
---echo RESTORE_FROM 'rpl_bup_m2.bak';
+--echo # Backup_id = 602.
+--echo # RESTORE_FROM 'rpl_bup_m2.bak';
 --disable_query_log
 eval RESTORE FROM '$MYSQLTEST_VARDIR/rpl_bup_m2.bak' OVERWRITE;
 --enable_query_log
 
---echo Showing databases on slave.
+--remove_file $MYSQLTEST_VARDIR/rpl_bup_m2.bak
+
+--echo # Showing databases on slave.
 SHOW DATABASES LIKE 'rpl_backup%';
 
 SELECT count(*) FROM rpl_backup.t1;
@@ -302,22 +330,25 @@ 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.
+--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.
 #
 
+--echo # Connecting to slave...
 connection slave;
 
---echo Test restore on slave while replication turned on.
+--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.
+--remove_file $MYSQLD_S_DATADIR/rpl_bup_s1.bak
+
+--echo # Stop slave and restart after restore.
 STOP SLAVE;
 
 --replace_column 1 #
@@ -326,12 +357,14 @@ RESTORE FROM 'rpl_bup_s3.bak' OVERWRITE;
 START SLAVE;
 --source include/wait_for_slave_to_start.inc
 
+--echo # Connecting to master...
 connection master;
 
---echo Checking affect on replication.
+--echo # Checking affect on replication.
 INSERT INTO rpl_backup.t1 VALUES (44), (55), (66);
 SELECT * FROM rpl_backup.t1 ORDER BY a;
 
+--echo # Connecting to slave...
 sync_slave_with_master;
 connection slave;
 SELECT * FROM rpl_backup.t1 ORDER BY a;
@@ -349,24 +382,26 @@ SELECT * FROM rpl_backup.t1 ORDER BY a;
 #        we have explicitly turned off binary logging. 
 #
 
---echo Stop replication and turn off binary log.
+--echo # Connecting to slave...
+--echo # Stop replication and turn off binary log.
 connection slave;
 
 STOP SLAVE;
 --source include/wait_for_slave_to_stop.inc
 
+--echo # Connecting to master...
 connection master;
 
 SET @orig_sql_log_bin= @@sql_log_bin;
 
---echo Turn off binlog.
+--echo # Turn off binlog.
 SET @@sql_log_bin= 0;
 SHOW VARIABLES LIKE '%log_bin';
 
---echo Backup_id = 503.
+--echo # Backup_id = 503.
 BACKUP DATABASE rpl_backup TO 'rpl_bup_m3.bak';
 
---echo Turn on binlog;
+--echo # Turn on binlog;
 SET @@sql_log_bin= @orig_sql_log_bin;
 SHOW VARIABLES LIKE '%log_bin';
 
@@ -376,27 +411,29 @@ SHOW VARIABLES LIKE '%log_bin';
 
 RESET MASTER;
 
---echo Get master's binlog position before restore.
+--echo # Get master's binlog position before restore.
 let $master_before_pos = query_get_value("SHOW MASTER STATUS", Position, 1);
 
---echo Backup_id = 504.
+--echo # Backup_id = 504.
 RESTORE FROM 'rpl_bup_m3.bak' OVERWRITE;
 
---echo Get master's binlog position after restore.
+--remove_file $MYSQLD_M_DATADIR/rpl_bup_m3.bak
+
+--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.
+--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.
+--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.
+--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
 
@@ -406,22 +443,25 @@ eval SELECT $master_after_pos - $master_
 
 RESET MASTER;
 
+--echo # Connecting to slave...
 connection slave;
 
 RESET SLAVE;
 
 SET DEBUG_SYNC = 'reset';
 
+--echo # Connecting to slave...
 connection slave1;
 
 SET DEBUG_SYNC = 'before_restore_done SIGNAL restore_running WAIT_FOR proceed';
 SEND RESTORE FROM 'rpl_bup_s3.bak' OVERWRITE;
 
+--echo # Connecting to slave...
 connection slave;
 
 SET DEBUG_SYNC = 'now WAIT_FOR restore_running';
 
---echo Try to start the slave while restore is running -- gets error.
+--echo # Try to start the slave while restore is running -- gets error.
 --error ER_RESTORE_CANNOT_START_SLAVE
 SLAVE START;
 
@@ -431,12 +471,16 @@ SET DEBUG_SYNC = 'now SIGNAL proceed';
 --replace_column 1 # 6 # 7 # 8 # 9 # 22 # 23 # 33 #
 --query_vertical SHOW SLAVE STATUS
 
+--echo # Connecting to slave...
 connection slave1;
---echo Restore is now complete.
+--echo # Restore is now complete.
 --replace_column 1 #
 reap;
 SET DEBUG_SYNC = 'now SIGNAL done';
 
+--remove_file $MYSQLD_S_DATADIR/rpl_bup_s3.bak
+
+--echo # Connecting to slave...
 connection slave;
 
 SET DEBUG_SYNC = 'now WAIT_FOR done';
@@ -445,7 +489,7 @@ SHOW DATABASES; 
 
 SET DEBUG_SYNC = 'reset';
 
---echo Try to start the slave after restore is done -- should succeed.
+--echo # Try to start the slave after restore is done -- should succeed.
 SLAVE START;
 --source include/wait_for_slave_to_start.inc
 
@@ -453,30 +497,97 @@ SLAVE START;
 --replace_column 1 # 6 # 7 # 8 # 9 # 10 # 22 # 23 # 33 #
 --query_vertical SHOW SLAVE STATUS
 
---echo Now stop the slave.
+--echo # Now stop the slave.
+SLAVE STOP;
+--source include/wait_for_slave_to_stop.inc
+
+#
+# Test case for BUG#39780 - Skip gap event on restore.
+#
+# The new SKIP_GAP_EVENT option for the RESTORE command
+# allows users to purposefully skip writing the gap event
+# when the restore is run on a master and the databases
+# being restored do not exist on the slave nor are they
+# intended to be on the slave.
+#
+
+--echo # Connecting to master...
+--echo # First, reset replication. 
+connection master;
+RESET MASTER;
+
+--echo # Connecting to slave...
+connection slave;
+RESET SLAVE;
+SET DEBUG_SYNC = 'reset';
+
+--echo # Connecting to slave...
+connection slave;
+START SLAVE;
+--source include/wait_for_slave_to_start.inc
+
+--echo # Connecting to master...
+--echo # Create a new database on the master. 
+connection master;
+
+CREATE DATABASE not_replicated;
+CREATE TABLE not_replicated.t1 (a int);
+INSERT INTO not_replicated.t1 VALUES (200), (300), (400);
+
+SHOW DATABASES;
+
+--echo # Connecting to slave...
+--echo # Now let's see if it is replicated on the slave (shouldn't be).
+sync_slave_with_master;
+connection slave;
+
+SHOW DATABASES;
+
+--echo # Connecting to master...
+--echo # Now back to the master to make a backup of the new database.
+connection master;
+
+--echo # Backup_id = 505.
+BACKUP DATABASE not_replicated TO 'rpl_bup_m4.bak';
+
+--echo # Now let's run the restore and see if the slave stops.
+--echo # Backup_id = 506.
+RESTORE FROM 'rpl_bup_m4.bak' OVERWRITE SKIP_GAP_EVENT;
+
+--remove_file $MYSQLD_M_DATADIR/rpl_bup_m4.bak
+
+--echo # Let's ensure replication is still running.
+INSERT INTO rpl_backup.t1 VALUES (901), (902), (903);
+
+--echo # Connecting to slave...
+sync_slave_with_master;
+connection slave;
+
+SELECT * FROM rpl_backup.t1 WHERE a > 900;
+
+--echo # Now stop the slave.
 SLAVE STOP;
 --source include/wait_for_slave_to_stop.inc
 
 #
 # Cleanup
 #
+
+--echo # Connecting to master...
 connection master;
 
 FLUSH BACKUP LOGS;
 PURGE BACKUP LOGS;
 DROP DATABASE rpl_backup;
+DROP DATABASE not_replicated;
 
---remove_file $MYSQLD_M_DATADIR/rpl_bup_m1.bak
---remove_file $MYSQLTEST_VARDIR/rpl_bup_m2.bak
---remove_file $MYSQLD_M_DATADIR/rpl_bup_m3.bak
 
+--echo # Connecting to slave...
 connection slave;
 
 FLUSH BACKUP LOGS;
 PURGE BACKUP LOGS;
 DROP DATABASE rpl_backup;
+DROP DATABASE not_replicated;
 
---remove_file $MYSQLD_S_DATADIR/rpl_bup_s1.bak
---remove_file $MYSQLD_S_DATADIR/rpl_bup_s2.bak
---remove_file $MYSQLD_S_DATADIR/rpl_bup_s3.bak
 

=== modified file 'sql/backup/backup_kernel.h'
--- a/sql/backup/backup_kernel.h	2009-01-13 12:57:55 +0000
+++ b/sql/backup/backup_kernel.h	2009-02-09 22:23:14 +0000
@@ -30,7 +30,11 @@ void backup_shutdown();
   Called from the big switch in mysql_execute_command() to execute
   backup related statement
 */
-int execute_backup_command(THD*, LEX*, String*, bool);
+int execute_backup_command(THD *thd, 
+                           LEX *lex, 
+                           String *backupdir, 
+                           bool overwrite,
+                           bool skip_gap_event);
 
 // forward declarations
 
@@ -73,7 +77,7 @@ public:
                                    const char*, bool);
   Restore_info* prepare_for_restore(String *location, 
                                    LEX_STRING orig_loc,
-                                   const char*);  
+                                   const char*, bool);  
 
   int do_backup();
   int do_restore(bool overwrite);

=== modified file 'sql/backup/kernel.cc'
--- a/sql/backup/kernel.cc	2009-02-09 18:17:55 +0000
+++ b/sql/backup/kernel.cc	2009-02-09 22:23:14 +0000
@@ -123,6 +123,9 @@ static int send_reply(Backup_restore_ctx
   @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
+  @param[in] skip_gap_event  whether or not restore should skip writing
+                             the gap event if run on a master in an active
+                             replication scenario
 
   @note This function sends response to the client (ok, result set or error).
 
@@ -134,7 +137,11 @@ static int send_reply(Backup_restore_ctx
  */
 
 int
-execute_backup_command(THD *thd, LEX *lex, String *backupdir, bool overwrite)
+execute_backup_command(THD *thd, 
+                       LEX *lex, 
+                       String *backupdir, 
+                       bool overwrite,
+                       bool skip_gap_event)
 {
   int res= 0;
   
@@ -209,7 +216,7 @@ execute_backup_command(THD *thd, LEX *le
   {
 
     Restore_info *info= context.prepare_for_restore(backupdir, lex->backup_dir, 
-                                                    thd->query);
+                                                    thd->query, skip_gap_event);
     
     if (!info || !info->is_valid())
       DBUG_RETURN(send_error(context, ER_BACKUP_RESTORE_PREPARE));
@@ -682,6 +689,7 @@ Backup_restore_ctx::prepare_for_backup(S
   @param[in] backupdir  path to the file where backup image is stored
   @param[in] orig_loc   path as specified on command line for backup image
   @param[in] query      RESTORE query starting the operation
+  @param[in] skip_gap_event TRUE means do not write gap event
   
   @returns Pointer to a @c Restore_info instance containing catalogue of the
   backup image (read from the image). NULL if errors were detected.
@@ -691,7 +699,8 @@ Backup_restore_ctx::prepare_for_backup(S
 Restore_info* 
 Backup_restore_ctx::prepare_for_restore(String *backupdir,
                                         LEX_STRING orig_loc, 
-                                        const char *query)
+                                        const char *query,
+                                        bool skip_gap_event)
 {
   using namespace backup;  
 
@@ -834,7 +843,8 @@ Backup_restore_ctx::prepare_for_restore(
 
     DEBUG_SYNC(m_thd, "after_disable_slave_connections");
 
-    obs::write_incident_event(m_thd, obs::RESTORE_EVENT);
+    if (!skip_gap_event)
+      obs::write_incident_event(m_thd, obs::RESTORE_EVENT);
     m_engage_binlog= TRUE;
     obs::engage_binlog(FALSE);
   }

=== modified file 'sql/lex.h'
--- a/sql/lex.h	2008-12-24 10:48:24 +0000
+++ b/sql/lex.h	2009-02-09 22:23:14 +0000
@@ -486,6 +486,7 @@ static SYMBOL symbols[] = {
   { "SHUTDOWN",		SYM(SHUTDOWN)},
   { "SIGNED",		SYM(SIGNED_SYM)},
   { "SIMPLE",		SYM(SIMPLE_SYM)},
+  { "SKIP_GAP_EVENT",     SYM(SKIP_GAP_EVENT_SYM)},
   { "SLAVE",            SYM(SLAVE)},
   { "SNAPSHOT",         SYM(SNAPSHOT_SYM)},
   { "SMALLINT",		SYM(SMALLINT)},

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2009-02-04 10:49:16 +0000
+++ b/sql/sql_parse.cc	2009-02-09 22:23:14 +0000
@@ -45,7 +45,7 @@
   @defgroup Runtime_Environment Runtime Environment
   @{
 */
-int execute_backup_command(THD*, LEX*, String*, bool);
+int execute_backup_command(THD*, LEX*, String*, bool, bool);
 
 /* Used in error handling only */
 #define SP_TYPE_STRING(LP) \
@@ -2325,26 +2325,43 @@ mysql_execute_command(THD *thd)
     /* Used to specify if RESTORE should overwrite existing db with same name */
     bool overwrite_restore= false;
 
-    Item *it= (Item *)lex->value_list.head();
+    /* Used to specify if RESTORE should skup writing the gap event. */
+    bool skip_gap_event= false;
+
+    List<Item> lit= lex->value_list;
+    Item *it= 0;
 
-    // Item only set for RESTORE in sql_yacc.yy, no error checking of
-    // item necessary
-    if (it)
+    // value list only set for RESTORE in sql_yacc.yy, no error checking of
+    // item necessary for backup
+    while (lit.elements)
     {
+      it= lit.pop();
       /*
         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;
+      int val= (int)it->val_int();
+      /*
+        Check options.
+      */
+      switch (val) {
+        /* OVERWRITE option */
+        case 1:
+          overwrite_restore= true;
+          break;
+        /* SKIP GAP EVENT option */
+        case 2:
+          skip_gap_event= true;
+          break;
+      }
     }
     /*
       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, overwrite_restore))
+    if (execute_backup_command(thd, lex, &backupdir, overwrite_restore,
+                               skip_gap_event))
       goto error;
     break;
   }

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2009-01-29 21:17:59 +0000
+++ b/sql/sql_yacc.yy	2009-02-09 22:23:14 +0000
@@ -1075,6 +1075,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  SHUTDOWN
 %token  SIGNED_SYM
 %token  SIMPLE_SYM                    /* SQL-2003-N */
+%token  SKIP_GAP_EVENT_SYM
 %token  SLAVE
 %token  SMALLINT                      /* SQL-2003-R */
 %token  SNAPSHOT_SYM
@@ -6461,7 +6462,7 @@ restore:
           }
           FROM
           TEXT_STRING_sys 
-          opt_overwrite
+          opt_overwrite opt_skip_gap_event
           {
             Lex->backup_dir = $4; 
           }
@@ -6485,6 +6486,23 @@ opt_overwrite:
             lex->value_list.push_front(it);
            }
          ;
+         
+opt_skip_gap_event:
+        /* empty */ 
+          {         
+            LEX *lex= Lex;
+            Item *it= new Item_int((int8) 0);
+
+            lex->value_list.push_back(it);
+          }
+        | SKIP_GAP_EVENT_SYM
+          {
+            LEX *lex= Lex;
+            Item *it= new Item_int((int8) 2);
+
+            lex->value_list.push_back(it);
+           }
+         ;
 
 backup:   
           BACKUP_SYM 

Thread
bzr commit into mysql-6.0-backup branch (charles.bell:2764) Bug#39780Chuck Bell9 Feb
  • Re: bzr commit into mysql-6.0-backup branch (charles.bell:2764)Bug#39780Ingo Strüwing10 Feb
  • Re: bzr commit into mysql-6.0-backup branch (charles.bell:2764)Bug#39780Jørgen Løland11 Feb