#At file:///home/oysteing/mysql/mysql-6.0-backup-1/
2724 oystein.grovlen@stripped 2008-11-04 [merge]
Merge with backup tree.
removed:
mysql-test/suite/backup/r/backup_view_on_view.result
mysql-test/suite/backup/t/backup_view_on_view.test
added:
mysql-test/suite/backup_engines/r/backup_tmp_tables.result
mysql-test/suite/backup_engines/t/backup_tmp_tables.test
mysql-test/suite/rpl/r/rpl_backup.result
mysql-test/suite/rpl/t/rpl_backup.test
modified:
sql/backup/backup_kernel.h
sql/backup/be_snapshot.cc
sql/backup/be_thread.cc
sql/backup/data_backup.cc
sql/backup/kernel.cc
sql/backup/logger.h
sql/log.cc
sql/log_event.cc
sql/share/errmsg.txt
sql/si_logs.cc
sql/si_logs.h
sql/si_objects.cc
=== 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;
=== 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_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-10-30 12:29:54 +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';
+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;
=== 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-10-30 12:29:54 +0000
@@ -0,0 +1,91 @@
+#
+# 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/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';
+
+#
+# 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-10-31 15:31:52 +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';
+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';
+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';
+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';
+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';
+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-10-31 15:31:52 +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';
+
+--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';
+
+--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';
+
+--echo Stop slave and restart after restore.
+STOP SLAVE;
+
+--replace_column 1 #
+RESTORE FROM 'rpl_bup_s3.bak';
+
+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';
+
+--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_kernel.h'
--- a/sql/backup/backup_kernel.h 2008-10-27 13:06:21 +0000
+++ b/sql/backup/backup_kernel.h 2008-10-30 17:53:24 +0000
@@ -134,6 +134,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-29 12:16:33 +0000
+++ b/sql/backup/data_backup.cc 2008-10-30 20:02:15 +0000
@@ -611,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);
@@ -638,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/kernel.cc'
--- a/sql/backup/kernel.cc 2008-10-28 14:17:05 +0000
+++ b/sql/backup/kernel.cc 2008-10-30 20:02:15 +0000
@@ -211,6 +211,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);
@@ -378,7 +385,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.
@@ -785,6 +793,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 +865,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 +957,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
=== modified file 'sql/backup/logger.h'
--- a/sql/backup/logger.h 2008-10-27 13:06:21 +0000
+++ b/sql/backup/logger.h 2008-10-30 17:53:24 +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&);
@@ -270,6 +272,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/log.cc'
--- a/sql/log.cc 2008-10-29 07:28:29 +0000
+++ b/sql/log.cc 2008-10-30 17:53:24 +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;
@@ -956,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;
}
@@ -2100,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++)->
@@ -4054,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_event.cc'
--- a/sql/log_event.cc 2008-10-20 19:13:22 +0000
+++ b/sql/log_event.cc 2008-10-31 15:31:52 +0000
@@ -9122,7 +9122,8 @@ 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));
=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt 2008-10-28 18:14:14 +0000
+++ b/sql/share/errmsg.txt 2008-10-30 17:53:24 +0000
@@ -6416,3 +6416,5 @@ 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."
=== 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-29 07:28:29 +0000
+++ b/sql/si_objects.cc 2008-10-30 12:29:54 +0000
@@ -2195,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);
| Thread |
|---|
| • bzr commit into mysql-6.0-backup branch (oystein.grovlen:2724) | Oystein.Grovlen | 4 Nov |