#At file:///Users/cbell/source/bzr/mysql-6.0-bug-47879/ based on revid:charles.bell@stripped
2889 Chuck Bell 2009-11-18 [merge]
Local merge before push of BUG#47879.
added:
mysql-test/suite/backup/r/backup_restore_locking.result
mysql-test/suite/backup/t/backup_restore_locking.test
modified:
client/mysqladmin.cc
mysql-test/collections/default.experimental
mysql-test/suite/backup/include/backup_ext.inc
mysql-test/suite/backup/include/backup_xpfm_compat_backup.inc
mysql-test/suite/backup/r/backup_errors.result
mysql-test/suite/backup/r/backup_errors_compression.result
mysql-test/suite/backup/r/backup_external.result
mysql-test/suite/backup/r/backup_intr_errors.result
mysql-test/suite/backup/r/backup_logs.result
mysql-test/suite/backup/r/backup_logs_output.result
mysql-test/suite/backup/r/backup_myisam.result
mysql-test/suite/backup/r/backup_myisam_coverage.result
mysql-test/suite/backup/r/backup_myisam_sync.result
mysql-test/suite/backup/r/backup_no_engine.result
mysql-test/suite/backup/t/backup_errors.test
mysql-test/suite/backup/t/backup_external.test
mysql-test/suite/backup/t/backup_external_non_win.test
mysql-test/suite/backup/t/backup_external_non_win_not_falcon.test
mysql-test/suite/backup/t/backup_logs.test
mysql-test/suite/backup/t/backup_logs_output.test
mysql-test/suite/backup/t/backup_myisam.test
mysql-test/suite/backup/t/backup_myisam_coverage.test
mysql-test/suite/backup/t/backup_myisam_sync.test
mysql-test/suite/backup/t/backup_no_engine.test
mysql-test/suite/backup_engines/r/backup_interruption.result
sql/backup/backup_info.cc
sql/backup/kernel.cc
sql/backup/logger.h
sql/backup/stream_v1_transport.c
sql/log.cc
sql/share/errmsg-utf8.txt
sql/share/errmsg.txt
sql/si_logs.cc
sql/si_logs.h
sql/si_objects.cc
sql/si_objects.h
sql/sql_base.cc
sql/sql_delete.cc
unittest/backup/bstr_callback_errors-t.c
unittest/backup/bstr_eos-t.c
unittest/backup/bstr_io_errors-t.c
unittest/backup/bstr_random_chunks-t.c
=== modified file 'client/mysqladmin.cc'
--- a/client/mysqladmin.cc 2009-11-02 14:05:19 +0000
+++ b/client/mysqladmin.cc 2009-11-16 15:21:34 +0000
@@ -97,7 +97,8 @@ enum commands {
ADMIN_FLUSH_HOSTS, ADMIN_FLUSH_TABLES, ADMIN_PASSWORD,
ADMIN_PING, ADMIN_EXTENDED_STATUS, ADMIN_FLUSH_STATUS,
ADMIN_FLUSH_PRIVILEGES, ADMIN_START_SLAVE, ADMIN_STOP_SLAVE,
- ADMIN_FLUSH_THREADS, ADMIN_OLD_PASSWORD, ADMIN_FLUSH_BACKUP_LOGS
+ ADMIN_FLUSH_THREADS, ADMIN_OLD_PASSWORD, ADMIN_FLUSH_BACKUP_LOGS,
+ ADMIN_PURGE_BUP_LOGS, ADMIN_PURGE_BUP_LOGS_ID, ADMIN_PURGE_BUP_LOGS_DATE
};
static const char *command_names[]= {
"create", "drop", "shutdown",
@@ -108,6 +109,7 @@ static const char *command_names[]= {
"ping", "extended-status", "flush-status",
"flush-privileges", "start-slave", "stop-slave",
"flush-threads", "old-password", "flush-backup-logs",
+ "purge-backup-logs", "purge-backup-logs-id", "purge-backup-logs-date",
NullS
};
@@ -895,6 +897,60 @@ static int execute_commands(MYSQL *mysql
}
break;
}
+ /*
+ We have three forms of this command:
+
+ PURGE BACKUP LOGS
+ PURGE BACKUP LOGS TO <id>
+ PURGE BACKUP LOGS BEFORE <date>
+ */
+ case ADMIN_PURGE_BUP_LOGS:
+ {
+ if (mysql_query(mysql,"purge backup logs"))
+ {
+ my_printf_error(0,"purge backup logs failed; error: '%s'", error_flags,
+ mysql_error(mysql));
+ return -1;
+ }
+ break;
+ }
+ case ADMIN_PURGE_BUP_LOGS_ID:
+ {
+ char buff[FN_REFLEN+20];
+ if (argc < 2)
+ {
+ my_printf_error(0, "Too few arguments to purge backup logs to",
+ error_flags);
+ return 1;
+ }
+ sprintf(buff,"PURGE BACKUP LOGS TO %s", argv[1]);
+ if (mysql_query(mysql, buff))
+ {
+ my_printf_error(0,"purge backup logs failed; error: '%s'", error_flags,
+ mysql_error(mysql));
+ return -1;
+ }
+ argc--; argv++;
+ break;
+ }
+ case ADMIN_PURGE_BUP_LOGS_DATE:
+ {
+ char buff[FN_REFLEN+20];
+ if (argc < 2)
+ {
+ my_printf_error(0, "Too few arguments to purge backup logs before",
+ error_flags);
+ }
+ sprintf(buff,"PURGE BACKUP LOGS BEFORE '%s'", argv[1]);
+ if (mysql_query(mysql, buff))
+ {
+ my_printf_error(0,"purge backup logs failed; error: '%s'", error_flags,
+ mysql_error(mysql));
+ return -1;
+ }
+ argc--; argv++;
+ break;
+ }
case ADMIN_FLUSH_STATUS:
{
if (mysql_query(mysql,"flush status"))
@@ -1106,7 +1162,10 @@ static void usage(void)
extended-status Gives an extended status message from the server\n\
flush-hosts Flush all cached hosts\n\
flush-logs Flush all logs\n\
- flush-backup-logs Flush backup logs\n\
+ flush-backup-logs Flush backup logs\n\
+ purge-backup-logs Purge backup logs\n\
+ purge-backup-logs-id <backup_id> Purge backup logs up to a given backup_id\n\
+ purge-backup-logs-date <datetime> Purge backup logs before a given datetime\n\
flush-status Clear status variables\n\
flush-tables Flush all tables\n\
flush-threads Flush the thread cache\n\
=== modified file 'mysql-test/collections/default.experimental'
--- a/mysql-test/collections/default.experimental 2009-11-02 14:05:19 +0000
+++ b/mysql-test/collections/default.experimental 2009-11-13 12:10:39 +0000
@@ -3,8 +3,6 @@
backup.backup_dbname_lctn2 @windows @darwin # Bug#46933 2009-08-26 alik backup_*_lctn2 tests fail on windows
backup.backup_events # Bug#47211 2009-09-25 alik backup_events.test fails randomly
-backup.backup_external_non_win* # BUG#45877
-backup.backup_logs # Bug#47698 2009-09-29 alik backup.backup_logs fails under valgrind
backup.backup_xpfm_compat_backup_lctn2 @windows # Bug#46933 2009-08-26 alik backup_*_lctn2 tests fail on windows
binlog.binlog_multi_engine # joro : NDB tests marked as experimental as agreed with bochklin
=== modified file 'mysql-test/suite/backup/include/backup_ext.inc'
--- a/mysql-test/suite/backup/include/backup_ext.inc 2009-03-25 22:17:35 +0000
+++ b/mysql-test/suite/backup/include/backup_ext.inc 2009-11-13 12:10:39 +0000
@@ -28,3 +28,6 @@ my $F = IO::File->new("$vardir/tmp/mctf.
print $F "let \$MYSQL_CONVERT_TABLE_FORMAT = $location;";
EOF
+
+--source $MYSQLTEST_VARDIR/tmp/mctf.inc
+
=== modified file 'mysql-test/suite/backup/include/backup_xpfm_compat_backup.inc'
--- a/mysql-test/suite/backup/include/backup_xpfm_compat_backup.inc 2009-07-20 09:27:48 +0000
+++ b/mysql-test/suite/backup/include/backup_xpfm_compat_backup.inc 2009-11-18 15:27:51 +0000
@@ -897,6 +897,11 @@ DROP USER 'no_user'@'%';
DROP USER 'bup_user1'@'%';
DROP USER 'BUP_USER2';
DROP USER 'BupUser3'@'%';
+# BUG#48850 : This test will hang on the DROP DATABASE commands.
+# Remove the FLUSH TABLES when this bug is fixed.
+--disable_query_log
+FLUSH TABLES;
+--enable_query_log
DROP DATABASE bup_xpfm_compat_db1;
DROP DATABASE BUP_XPFM_COMPAT_DB2;
DROP DATABASE BupXPfmCompat_db3;
=== modified file 'mysql-test/suite/backup/r/backup_errors.result'
--- a/mysql-test/suite/backup/r/backup_errors.result 2009-10-21 12:15:53 +0000
+++ b/mysql-test/suite/backup/r/backup_errors.result 2009-11-17 20:18:50 +0000
@@ -595,6 +595,37 @@ SET SESSION DEBUG='-d';
#
# Test error handling by injecting errors into BACKUP
#
+# non-existent database
+DROP DATABASE IF EXISTS db1;
+DROP DATABASE IF EXISTS db2;
+CREATE DATABASE db1;
+USE db1;
+CREATE TABLE db1_tab (i int);
+INSERT INTO db1_tab VALUES (1), (2), (3);
+CREATE DATABASE db2;
+USE db2;
+CREATE TABLE db2_tab (v varchar(64));
+INSERT INTO db2_tab VALUES ("This is table db2_tab");
+#
+# Backup without error injection
+#
+SET SESSION DEBUG='-d';
+BACKUP DATABASE * TO 'all.bak' OVERWRITE;
+backup_id
+#
+SHOW WARNINGS;
+Level Code Message
+#
+# Error injection in user privileges checking
+#
+SET SESSION DEBUG='+d,ER_BACKUP_USER_PRIV_CHECK_add_db';
+BACKUP DATABASE db1 TO 'db1.bak' OVERWRITE;
+ERROR HY000: Failed to perform access privileges check for user 'root'.
+SET SESSION DEBUG='-d';
+SET SESSION DEBUG='+d,ER_BACKUP_USER_PRIV_CHECK_add_all_dbs';
+BACKUP DATABASE * TO 'all.bak' OVERWRITE;
+ERROR HY000: Failed to perform access privileges check for user 'root'.
+SET SESSION DEBUG='-d';
#
# Error injection in si_object.cc:get_database_stub
#
@@ -606,3 +637,4 @@ SET SESSION DEBUG='-d';
# Cleanup
#
DROP DATABASE db1;
+DROP DATABASE db2;
=== modified file 'mysql-test/suite/backup/r/backup_errors_compression.result'
--- a/mysql-test/suite/backup/r/backup_errors_compression.result 2009-10-23 15:41:56 +0000
+++ b/mysql-test/suite/backup/r/backup_errors_compression.result 2009-11-17 20:18:50 +0000
@@ -595,6 +595,37 @@ SET SESSION DEBUG='-d';
#
# Test error handling by injecting errors into BACKUP
#
+# non-existent database
+DROP DATABASE IF EXISTS db1;
+DROP DATABASE IF EXISTS db2;
+CREATE DATABASE db1;
+USE db1;
+CREATE TABLE db1_tab (i int);
+INSERT INTO db1_tab VALUES (1), (2), (3);
+CREATE DATABASE db2;
+USE db2;
+CREATE TABLE db2_tab (v varchar(64));
+INSERT INTO db2_tab VALUES ("This is table db2_tab");
+#
+# Backup without error injection
+#
+SET SESSION DEBUG='-d';
+BACKUP DATABASE * TO 'all.bak' OVERWRITE;
+backup_id
+#
+SHOW WARNINGS;
+Level Code Message
+#
+# Error injection in user privileges checking
+#
+SET SESSION DEBUG='+d,ER_BACKUP_USER_PRIV_CHECK_add_db';
+BACKUP DATABASE db1 TO 'db1.bak' OVERWRITE;
+ERROR HY000: Failed to perform access privileges check for user 'root'.
+SET SESSION DEBUG='-d';
+SET SESSION DEBUG='+d,ER_BACKUP_USER_PRIV_CHECK_add_all_dbs';
+BACKUP DATABASE * TO 'all.bak' OVERWRITE;
+ERROR HY000: Failed to perform access privileges check for user 'root'.
+SET SESSION DEBUG='-d';
#
# Error injection in si_object.cc:get_database_stub
#
@@ -606,3 +637,4 @@ SET SESSION DEBUG='-d';
# Cleanup
#
DROP DATABASE db1;
+DROP DATABASE db2;
=== modified file 'mysql-test/suite/backup/r/backup_external.result'
--- a/mysql-test/suite/backup/r/backup_external.result 2009-05-22 13:44:56 +0000
+++ b/mysql-test/suite/backup/r/backup_external.result 2009-11-16 19:20:34 +0000
@@ -184,6 +184,8 @@ Index_Comment
# Test 1: Use myisampack to compress the tables followed by myisamchk to
# rebuild the indexes.
+# exec myisampack
+# exec myisamchk
SHOW INDEX FROM db1.t1;;
Table t1
Non_unique 1
@@ -203,9 +205,17 @@ BACKUP DATABASE db1 TO 'db1.bak';
backup_id
#
DROP DATABASE db1;
+# RESTORE of a compressed MyISAM table issues two warnings:
+# "Table is read only" and "Deadlock found when trying to get lock".
+# This results from an internal call of FLUSH TABLES.
+# RESTORE can't get back its write lock on the now compressed table.
+# But it doesn't need the locks any more at this moment. So it's ok.
RESTORE FROM 'db1.bak';
backup_id
#
+Warnings:
+# 1036 Table 't1' is read only
+# 1213 Deadlock found when trying to get lock; try restarting transaction
SHOW INDEX FROM db1.t1;;
Table t1
Non_unique 1
@@ -233,6 +243,9 @@ id name
# Use myisampack utility again after restore. Verify that utilities
# are not affected and functions properly after backup and restore
# operation.
+# exec myisamchk
+# exec myisampack
+# exec myisamchk
SHOW INDEX FROM db1.t1;;
Table t1
Non_unique 1
@@ -261,14 +274,24 @@ id name
# Bug#42572 - Restore fails when myisampack used with -b option
#
# Use myisampack -b option to make backup of table datafile
+# exec myisamchk
+# exec myisampack
+# exec myisamchk
BACKUP DATABASE db1 TO 'db1b.bak';
backup_id
#
+# RESTORE of a compressed MyISAM table issues two warnings:
+# "Table is read only" and "Deadlock found when trying to get lock".
+# This results from an internal call of FLUSH TABLES.
+# RESTORE can't get back its write lock on the now compressed table.
+# But it doesn't need the locks any more at this moment. So it's ok.
RESTORE FROM 'db1b.bak' OVERWRITE;
backup_id
#
Warnings:
# # Renamed directory with unknown files to 'db1-#'
+# # Table 't1' is read only
+# # Deadlock found when trying to get lock; try restarting transaction
SHOW TABLES FROM db1;
Tables_in_db1
t1
@@ -318,9 +341,17 @@ backup_id
#
DROP DATABASE db1;
DROP DATABASE db2;
+# RESTORE of a compressed MyISAM table issues two warnings:
+# "Table is read only" and "Deadlock found when trying to get lock".
+# This results from an internal call of FLUSH TABLES.
+# RESTORE can't get back its write lock on the now compressed table.
+# But it doesn't need the locks any more at this moment. So it's ok.
RESTORE FROM 'db12.bak';
backup_id
#
+Warnings:
+# 1036 Table 't1' is read only
+# 1213 Deadlock found when trying to get lock; try restarting transaction
CHECKSUM TABLE db1.t1;
Table Checksum
db1.t1 261218912
@@ -505,9 +536,17 @@ backup_id
#
DROP DATABASE db1;
DROP DATABASE db2;
+# RESTORE of a compressed MyISAM table issues two warnings:
+# "Table is read only" and "Deadlock found when trying to get lock".
+# This results from an internal call of FLUSH TABLES.
+# RESTORE can't get back its write lock on the now compressed table.
+# But it doesn't need the locks any more at this moment. So it's ok.
RESTORE FROM 'db12.bak';
backup_id
#
+Warnings:
+# 1036 Table 't1' is read only
+# 1213 Deadlock found when trying to get lock; try restarting transaction
SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
COUNT(*)
128
=== modified file 'mysql-test/suite/backup/r/backup_intr_errors.result'
--- a/mysql-test/suite/backup/r/backup_intr_errors.result 2009-10-12 09:08:34 +0000
+++ b/mysql-test/suite/backup/r/backup_intr_errors.result 2009-11-16 19:20:34 +0000
@@ -112,6 +112,8 @@ SHOW WARNINGS;
Level Code Message
Error <error-code> Query execution was interrupted
Error <error-code> Can't shut down Snapshot restore driver(s)
+Error <error-code> Query execution was interrupted
+Error <error-code> Query execution was interrupted
Warning <error-code> Operation aborted - data might be corrupted
Error <error-code> Backup/Restore: Error on close of backup stream
#
@@ -238,6 +240,8 @@ SHOW WARNINGS;
Level Code Message
Error <error-code> Query execution was interrupted
Error <error-code> Can't shut down Default restore driver(s)
+Error <error-code> Query execution was interrupted
+Error <error-code> Query execution was interrupted
Warning <error-code> Operation aborted - data might be corrupted
Error <error-code> Backup/Restore: Error on close of backup stream
#
=== modified file 'mysql-test/suite/backup/r/backup_logs.result'
--- a/mysql-test/suite/backup/r/backup_logs.result 2009-11-04 14:18:21 +0000
+++ b/mysql-test/suite/backup/r/backup_logs.result 2009-11-10 17:24:18 +0000
@@ -205,12 +205,6 @@ Turn off debugging session.
SET SESSION debug="-d";
SET time_zone='+0:00';
SELECT now() INTO @stop_backup;
-We calculate the timedifference between backup start time and stop
-time. If this difference is '0', then backup start time and stop time
-are same.
-SELECT timediff(@stop_backup, @start_backup) > 5;
-timediff(@stop_backup, @start_backup) > 5
-0
Now verify actual start time / stop time of backup and start time /
stop time from backup_history table. If the both times are same,
=== modified file 'mysql-test/suite/backup/r/backup_logs_output.result'
--- a/mysql-test/suite/backup/r/backup_logs_output.result 2009-10-26 09:16:48 +0000
+++ b/mysql-test/suite/backup/r/backup_logs_output.result 2009-11-16 15:21:34 +0000
@@ -238,6 +238,51 @@ count(*)
6
FLUSH BACKUP LOGS;
Test flush-backup-logs from mysqladmin
+#
+# Test purge-backup-logs from mysqladmin
+#
+#
+# Do another backup here then try next version of purge backup logs
+#
+BACKUP DATABASE bup_log TO 'bup_log.bak';
+backup_id
+#
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+1
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+6
+#
+# Test purge-backup-logs-to from mysqladmin
+#
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+0
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+0
+#
+# Do another backup here then try next version of purge backup logs
+#
+BACKUP DATABASE bup_log TO 'bup_log.bak';
+backup_id
+#
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+1
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+6
+#
+# Test purge-backup-logs-date from mysqladmin
+#
+SELECT count(*) FROM mysql.backup_history;
+count(*)
+0
+SELECT count(*) FROM mysql.backup_progress;
+count(*)
+0
SET GLOBAL backup_history_log=0;
SET GLOBAL backup_progress_log=0;
Should show 'OFF'
=== modified file 'mysql-test/suite/backup/r/backup_myisam.result'
--- a/mysql-test/suite/backup/r/backup_myisam.result 2009-02-13 12:40:13 +0000
+++ b/mysql-test/suite/backup/r/backup_myisam.result 2009-11-16 19:20:34 +0000
@@ -15,12 +15,22 @@ INSERT INTO mysql_db1.t1 SELECT * FROM m
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
FLUSH TABLE mysql_db1.t1;
+# exec myisampack
+# exec myisamchk
BACKUP DATABASE mysql_db1 to 'bup_myisam.bak';
backup_id
-#
+###
+# RESTORE of a compressed MyISAM table issues two warnings:
+# "Table is read only" and "Deadlock found when trying to get lock".
+# This results from an internal call of FLUSH TABLES.
+# RESTORE can't get back its write lock on the now compressed table.
+# But it doesn't need the locks any more at this moment. So it's ok.
RESTORE FROM 'bup_myisam.bak' OVERWRITE;
backup_id
-#
+###
+Warnings:
+### 1036 Table 't1' is read only
+### 1213 Deadlock found when trying to get lock; try restarting transaction
SELECT COUNT(*) FROM mysql_db1.t1 WHERE c2 < 5;
COUNT(*)
128
=== modified file 'mysql-test/suite/backup/r/backup_myisam_coverage.result'
--- a/mysql-test/suite/backup/r/backup_myisam_coverage.result 2008-12-30 12:13:31 +0000
+++ b/mysql-test/suite/backup/r/backup_myisam_coverage.result 2009-11-16 19:20:34 +0000
@@ -12,13 +12,23 @@ INSERT INTO mysql_db1.t1 SELECT * FROM m
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
FLUSH TABLE mysql_db1.t1;
+# exec myisampack
+# exec myisamchk
BACKUP DATABASE mysql_db1 to 'bup_myisam3.bak';
backup_id
#
SET debug='d,Backup_restore_ctx_unlock_tables_alloc';
+# RESTORE of a compressed MyISAM table issues two warnings:
+# "Table is read only" and "Deadlock found when trying to get lock".
+# This results from an internal call of FLUSH TABLES.
+# RESTORE can't get back its write lock on the now compressed table.
+# But it doesn't need the locks any more at this moment. So it's ok.
RESTORE FROM 'bup_myisam3.bak' OVERWRITE;
backup_id
#
+Warnings:
+# 1036 Table 't1' is read only
+# 1213 Deadlock found when trying to get lock; try restarting transaction
SELECT COUNT(*) FROM mysql_db1.t1 WHERE c2 < 5;
COUNT(*)
128
=== modified file 'mysql-test/suite/backup/r/backup_myisam_sync.result'
--- a/mysql-test/suite/backup/r/backup_myisam_sync.result 2009-04-14 13:40:06 +0000
+++ b/mysql-test/suite/backup/r/backup_myisam_sync.result 2009-11-16 19:20:34 +0000
@@ -76,7 +76,57 @@ VARIABLE_NAME LIKE 'Key_blocks_%used';
key_cache_is_enabled
1
-# final cleanup
+# cleanup
USE test;
DROP DATABASE mysqltest;
SET DEBUG_SYNC= 'RESET';
+#
+# Bug#40944 - Backup: crash after myisampack
+# Patch #2
+#
+CREATE DATABASE bup_myisam_sync_db1;
+CREATE TABLE bup_myisam_sync_db1.t1 (c1 VARCHAR(5), c2 int) ENGINE=MyISAM;
+CREATE INDEX i1 ON bup_myisam_sync_db1.t1 (c1, c2);
+INSERT INTO bup_myisam_sync_db1.t1 VALUES ('A',1);
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+FLUSH TABLE bup_myisam_sync_db1.t1;
+# exec myisampack
+# exec myisamchk
+BACKUP DATABASE bup_myisam_sync_db1 to 'bup_myisam_sync_db1.bak';
+backup_id
+#
+DROP DATABASE bup_myisam_sync_db1;
+SET DEBUG_SYNC= 'after_restore_locks_tables SIGNAL restore_locked
+ WAIT_FOR restore_finish';
+RESTORE FROM 'bup_myisam_sync_db1.bak';
+#
+# connection con1
+SET DEBUG_SYNC= 'now WAIT_FOR restore_locked';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL restore_finish';
+SELECT COUNT(*) FROM bup_myisam_sync_db1.t1 WHERE c2 < 5;
+#
+# connection default
+# RESTORE of a compressed MyISAM table issues two warnings:
+# "Table is read only" and "Deadlock found when trying to get lock".
+# This results from an internal call of FLUSH TABLES.
+# RESTORE can't get back its write lock on the now compressed table.
+# But it doesn't need the locks any more at this moment. So it's ok.
+backup_id
+###
+Warnings:
+### 1036 Table 't1' is read only
+### 1213 Deadlock found when trying to get lock; try restarting transaction
+#
+# connection con1
+COUNT(*)
+128
+#
+# connection default
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE bup_myisam_sync_db1;
=== modified file 'mysql-test/suite/backup/r/backup_no_engine.result'
--- a/mysql-test/suite/backup/r/backup_no_engine.result 2009-06-18 11:28:01 +0000
+++ b/mysql-test/suite/backup/r/backup_no_engine.result 2009-11-09 10:56:12 +0000
@@ -1,3 +1,6 @@
+Suppress this error in the server log
+call mtr.add_suppression("Can't access storage engine of table ");
+
DROP DATABASE IF EXISTS db;
CREATE DATABASE db;
CREATE TABLE db.t1 (a int, b char(32));
@@ -6,19 +9,10 @@ Tables_in_db
t1
t2
BACKUP DATABASE db TO "db.backup";
-backup_id
-#
-DROP DATABASE db;
-RESTORE FROM "db.backup";
-backup_id
-#
-SHOW TABLES IN db;
-Tables_in_db
-t1
-SHOW CREATE TABLE db.t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `a` int(11) DEFAULT NULL,
- `b` char(32) DEFAULT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ERROR 42000: Unknown storage engine 'PARADOX'
+SHOW WARNINGS;
+Level Code Message
+Error 1286 Unknown storage engine 'PARADOX'
+Error 1642 Can't access storage engine of table `db`.`t2`
+Warning 1777 Operation aborted
DROP DATABASE db;
=== added file 'mysql-test/suite/backup/r/backup_restore_locking.result'
--- a/mysql-test/suite/backup/r/backup_restore_locking.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/r/backup_restore_locking.result 2009-11-16 19:20:34 +0000
@@ -0,0 +1,148 @@
+call mtr.add_suppression("Restore: Open and lock tables failed in RESTORE");
+#
+# Precautionary cleanup
+#
+SET DEBUG_SYNC= 'RESET';
+SET @old_sessiondebug=@@session.debug;
+DROP DATABASE IF EXISTS bup_reslock_db1;
+#
+# Bug#41716 - Backup Error when sending data (for table #1)
+# to Default/Snapshot restore driver
+#
+CREATE DATABASE bup_reslock_db1;
+USE bup_reslock_db1;
+CREATE TABLE t1 (c1 INT, c2 VARCHAR(100), UNIQUE(c1)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES (1,"abc");
+BACKUP DATABASE bup_reslock_db1 TO 'bup_reslock_db1.bak';
+backup_id
+###
+DROP DATABASE bup_reslock_db1;
+SET DEBUG_SYNC= 'before_restore_locks_tables SIGNAL restore_before_locking
+ WAIT_FOR restore_finish';
+RESTORE FROM 'bup_reslock_db1.bak';
+#
+# connection con1
+SET DEBUG_SYNC= 'now WAIT_FOR restore_before_locking';
+INSERT INTO bup_reslock_db1.t1 VALUES(1,"def");
+SET DEBUG_SYNC= 'now SIGNAL restore_finish';
+#
+# connection default, retrieve RESTORE result.
+backup_id
+###
+SET DEBUG_SYNC= 'RESET';
+SELECT * FROM t1;
+c1 c2
+1 abc
+FLUSH TABLE t1;
+SELECT * FROM t1;
+c1 c2
+1 abc
+USE test;
+DROP DATABASE bup_reslock_db1;
+#
+# WL#4844 - Implement a locking scheme for RESTORE
+#
+CREATE DATABASE bup_reslock_db1;
+USE bup_reslock_db1;
+CREATE TABLE t1 (c1 INT, c2 VARCHAR(100), UNIQUE(c1)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES (0,"backup");
+BACKUP DATABASE bup_reslock_db1 TO 'bup_reslock_db1.bak';
+backup_id
+###
+DROP DATABASE bup_reslock_db1;
+SET DEBUG_SYNC= 'after_restore_lock_tables_for_write
+ SIGNAL waiting WAIT_FOR continue';
+SET DEBUG_SYNC= 'after_restore_truncate_tables
+ SIGNAL waiting WAIT_FOR continue';
+SET DEBUG_SYNC= 'before_restore_flush_tables
+ SIGNAL waiting WAIT_FOR continue';
+SET DEBUG_SYNC= 'before_restore_unlock_tables
+ SIGNAL waiting WAIT_FOR continue';
+RESTORE FROM 'bup_reslock_db1.bak';
+#
+# connection con1
+SET DEBUG_SYNC= 'now WAIT_FOR waiting';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+INSERT INTO bup_reslock_db1.t1 VALUES(1,"after_lock_tables");
+#
+# connection con2
+SET DEBUG_SYNC= 'now WAIT_FOR lock_wait';
+SET DEBUG_SYNC= 'now SIGNAL continue WAIT_FOR waiting';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+INSERT INTO bup_reslock_db1.t1 VALUES(2,"after_truncate_tables");
+#
+# connection con3
+SET DEBUG_SYNC= 'now SIGNAL continue WAIT_FOR waiting';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+INSERT INTO bup_reslock_db1.t1 VALUES(3,"before_flush_tables");
+#
+# connection con4
+SET DEBUG_SYNC= 'now WAIT_FOR lock_wait';
+SET DEBUG_SYNC= 'now SIGNAL continue WAIT_FOR waiting';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+INSERT INTO bup_reslock_db1.t1 VALUES(4,"before_unlock_tables");
+#
+# connection con5
+SET DEBUG_SYNC= 'now WAIT_FOR lock_wait';
+SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST;
+state info
+executing SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
+Table lock INSERT INTO bup_reslock_db1.t1 VALUES(4,"before_unlock_tables")
+Table lock INSERT INTO bup_reslock_db1.t1 VALUES(3,"before_flush_tables")
+Table lock INSERT INTO bup_reslock_db1.t1 VALUES(2,"after_truncate_tables")
+Table lock INSERT INTO bup_reslock_db1.t1 VALUES(1,"after_lock_tables")
+debug sync point: before_restore_unlock_tables RESTORE FROM 'bup_reslock_db1.bak'
+SET DEBUG_SYNC= 'now SIGNAL continue';
+#
+# connection default, retrieve RESTORE result
+backup_id
+###
+SET DEBUG_SYNC= 'RESET';
+#
+# connection con1, retrieve INSERT result.
+#
+# connection con2, retrieve INSERT result.
+#
+# connection con3, retrieve INSERT result.
+#
+# connection con4, retrieve INSERT result.
+#
+# connection default
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+0 backup
+1 after_lock_tables
+2 after_truncate_tables
+3 before_flush_tables
+4 before_unlock_tables
+FLUSH TABLE t1;
+SELECT * FROM t1 ORDER BY c1;
+c1 c2
+0 backup
+1 after_lock_tables
+2 after_truncate_tables
+3 before_flush_tables
+4 before_unlock_tables
+USE test;
+DROP DATABASE bup_reslock_db1;
+#
+# WL#4844 - Implement a locking scheme for RESTORE
+# Code coverage tests.
+#
+SET DEBUG='+d,error_inject_truncate_enter';
+RESTORE FROM 'bup_reslock_db1.bak';
+ERROR HY000: Open and lock tables failed in RESTORE
+SET debug=@old_sessiondebug;
+DROP DATABASE bup_reslock_db1;
+SET DEBUG_SYNC='after_restore_truncate_tables SIGNAL sync WAIT_FOR go';
+RESTORE FROM 'bup_reslock_db1.bak';
+#
+# connection con1
+SET DEBUG_SYNC= 'now WAIT_FOR sync';
+KILL QUERY ##;
+SET DEBUG_SYNC= 'now SIGNAL go';
+#
+# connection default, retrieve RESTORE result.
+ERROR 70100: Query execution was interrupted
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE bup_reslock_db1;
=== modified file 'mysql-test/suite/backup/t/backup_errors.test'
--- a/mysql-test/suite/backup/t/backup_errors.test 2009-10-21 12:15:53 +0000
+++ b/mysql-test/suite/backup/t/backup_errors.test 2009-11-17 20:18:50 +0000
@@ -697,6 +697,45 @@ SET SESSION DEBUG='-d';
--echo # Test error handling by injecting errors into BACKUP
--echo #
+--echo # non-existent database
+--disable_warnings
+DROP DATABASE IF EXISTS db1;
+DROP DATABASE IF EXISTS db2;
+--enable_warnings
+
+CREATE DATABASE db1;
+USE db1;
+CREATE TABLE db1_tab (i int);
+INSERT INTO db1_tab VALUES (1), (2), (3);
+
+CREATE DATABASE db2;
+USE db2;
+CREATE TABLE db2_tab (v varchar(64));
+INSERT INTO db2_tab VALUES ("This is table db2_tab");
+
+--echo #
+--echo # Backup without error injection
+--echo #
+SET SESSION DEBUG='-d';
+--replace_column 1 #
+BACKUP DATABASE * TO 'all.bak' OVERWRITE;
+SHOW WARNINGS;
+
+--echo #
+--echo # Error injection in user privileges checking
+--echo #
+SET SESSION DEBUG='+d,ER_BACKUP_USER_PRIV_CHECK_add_db';
+
+--error ER_BACKUP_USER_PRIV_CHECK
+BACKUP DATABASE db1 TO 'db1.bak' OVERWRITE;
+SET SESSION DEBUG='-d';
+
+SET SESSION DEBUG='+d,ER_BACKUP_USER_PRIV_CHECK_add_all_dbs';
+
+--error ER_BACKUP_USER_PRIV_CHECK
+BACKUP DATABASE * TO 'all.bak' OVERWRITE;
+SET SESSION DEBUG='-d';
+
--echo #
--echo # Error injection in si_object.cc:get_database_stub
--echo #
@@ -710,6 +749,7 @@ SET SESSION DEBUG='-d';
--echo #
DROP DATABASE db1;
+DROP DATABASE db2;
--remove_file $MYSQLD_DATADIR/errorinject.bak
=== modified file 'mysql-test/suite/backup/t/backup_external.test'
--- a/mysql-test/suite/backup/t/backup_external.test 2009-05-22 13:44:56 +0000
+++ b/mysql-test/suite/backup/t/backup_external.test 2009-11-16 19:20:34 +0000
@@ -108,7 +108,9 @@ INSERT INTO db2.t2 VALUES
# Myisamchk uses -s for silent mode, r for recovery and q for quick repair of
# datafiles
+--echo # exec myisampack
--exec $MYISAMPACK -s $MYSQLD_DATADIR/db1/t1.MYI
+--echo # exec myisamchk
--exec $MYISAMCHK -srq $MYSQLD_DATADIR/db1/t1.MYI
# Check the indexes in the table db1.t1
@@ -123,6 +125,11 @@ BACKUP DATABASE db1 TO 'db1.bak';
DROP DATABASE db1;
# Perform restore
+--echo # RESTORE of a compressed MyISAM table issues two warnings:
+--echo # "Table is read only" and "Deadlock found when trying to get lock".
+--echo # This results from an internal call of FLUSH TABLES.
+--echo # RESTORE can't get back its write lock on the now compressed table.
+--echo # But it doesn't need the locks any more at this moment. So it's ok.
--replace_column 1 #
RESTORE FROM 'db1.bak';
@@ -137,8 +144,11 @@ SELECT * FROM db1.t1 LIMIT 4;
--echo # are not affected and functions properly after backup and restore
--echo # operation.
+--echo # exec myisamchk
--exec $MYISAMCHK -s --unpack $MYSQLD_DATADIR/db1/t1.MYI
+--echo # exec myisampack
--exec $MYISAMPACK -s $MYSQLD_DATADIR/db1/t1.MYI
+--echo # exec myisamchk
--exec $MYISAMCHK -srq $MYSQLD_DATADIR/db1/t1.MYI
# Check the indexes in the table db1.t1
@@ -154,8 +164,11 @@ SELECT * FROM db1.t1 LIMIT 4;
--echo #
--echo # Use myisampack -b option to make backup of table datafile
+--echo # exec myisamchk
--exec $MYISAMCHK -s --unpack $MYSQLD_DATADIR/db1/t1.MYI
+--echo # exec myisampack
--exec $MYISAMPACK -s -b $MYSQLD_DATADIR/db1/t1.MYI
+--echo # exec myisamchk
--exec $MYISAMCHK -srq $MYSQLD_DATADIR/db1/t1.MYI
# Execute backup operation
@@ -163,6 +176,11 @@ SELECT * FROM db1.t1 LIMIT 4;
BACKUP DATABASE db1 TO 'db1b.bak';
# Perform restore
+--echo # RESTORE of a compressed MyISAM table issues two warnings:
+--echo # "Table is read only" and "Deadlock found when trying to get lock".
+--echo # This results from an internal call of FLUSH TABLES.
+--echo # RESTORE can't get back its write lock on the now compressed table.
+--echo # But it doesn't need the locks any more at this moment. So it's ok.
# Mask UUID and path delimiter.
--replace_regex /db1-[^']*/db1-#/ /'\.[\/\\]/'/
# Mask backup_id and warning numbers.
@@ -220,6 +238,11 @@ DROP DATABASE db1;
DROP DATABASE db2;
# Perform restore
+--echo # RESTORE of a compressed MyISAM table issues two warnings:
+--echo # "Table is read only" and "Deadlock found when trying to get lock".
+--echo # This results from an internal call of FLUSH TABLES.
+--echo # RESTORE can't get back its write lock on the now compressed table.
+--echo # But it doesn't need the locks any more at this moment. So it's ok.
--replace_column 1 #
RESTORE FROM 'db12.bak';
@@ -308,6 +331,11 @@ DROP DATABASE db1;
DROP DATABASE db2;
# Perform restore
+--echo # RESTORE of a compressed MyISAM table issues two warnings:
+--echo # "Table is read only" and "Deadlock found when trying to get lock".
+--echo # This results from an internal call of FLUSH TABLES.
+--echo # RESTORE can't get back its write lock on the now compressed table.
+--echo # But it doesn't need the locks any more at this moment. So it's ok.
--replace_column 1 #
RESTORE FROM 'db12.bak';
=== modified file 'mysql-test/suite/backup/t/backup_external_non_win.test'
--- a/mysql-test/suite/backup/t/backup_external_non_win.test 2009-06-13 10:12:02 +0000
+++ b/mysql-test/suite/backup/t/backup_external_non_win.test 2009-11-13 12:10:39 +0000
@@ -12,6 +12,11 @@
--source suite/backup/include/backup_ext.inc
--source suite/backup/include/have_dbi.inc
+if(`select "$MYSQL_CONVERT_TABLE_FORMAT" NOT LIKE '%convert_table_format%'`)
+{
+--skip Could not find mysql_convert_table_format utility.
+}
+
let $MYSQLD_BACKUPDIR = `select @@backupdir`;
let $MYSQLD_DATADIR= `select @@datadir`;
@@ -75,7 +80,6 @@ INSERT INTO db2.t1(b,c) VALUES
# Changing the storage engine for db1
SHOW CREATE TABLE db1.t1;
-source $MYSQLTEST_VARDIR/tmp/mctf.inc;
--exec perl $MYSQL_CONVERT_TABLE_FORMAT --user=root -S $MASTER_MYSOCK --port=$MASTER_MYPORT --type=innodb db1
--echo
@@ -96,7 +100,6 @@ RESTORE FROM 'db1.bak';
SHOW CREATE TABLE db1.t1;
--echo # Changing the storage engine back to myisam
-source $MYSQLTEST_VARDIR/tmp/mctf.inc;
--exec perl $MYSQL_CONVERT_TABLE_FORMAT -u root -S $MASTER_MYSOCK --port=$MASTER_MYPORT db1
SHOW CREATE TABLE db1.t1;
@@ -156,7 +159,6 @@ BACKUP DATABASE db1 TO 'db1.bak';
--echo # tables in db1
--disable_warnings
-source $MYSQLTEST_VARDIR/tmp/mctf.inc;
--exec perl $MYSQL_CONVERT_TABLE_FORMAT -u root -S $MASTER_MYSOCK --port=$MASTER_MYPORT --type=myisam db1
--enable_warnings
@@ -191,7 +193,6 @@ RESTORE FROM 'db1.bak' OVERWRITE;
--echo # Verify that tablespace is restored from db1.t2
SHOW CREATE TABLE db1.t2;
-source $MYSQLTEST_VARDIR/tmp/mctf.inc;
--exec perl $MYSQL_CONVERT_TABLE_FORMAT -u root -S $MASTER_MYSOCK --port=$MASTER_MYPORT --type=falcon db1
SHOW CREATE TABLE db1.tpl;
@@ -224,7 +225,6 @@ DROP VIEW db2.v1;
--remove_file $MYSQLD_BACKUPDIR/db1.bak
--echo # Changing the storage engine back to myisam after restore
-source $MYSQLTEST_VARDIR/tmp/mctf.inc;
--exec perl $MYSQL_CONVERT_TABLE_FORMAT -u root -S $MASTER_MYSOCK --port=$MASTER_MYPORT db1
SHOW CREATE TABLE db1.t1;
=== modified file 'mysql-test/suite/backup/t/backup_external_non_win_not_falcon.test'
--- a/mysql-test/suite/backup/t/backup_external_non_win_not_falcon.test 2009-06-30 07:51:04 +0000
+++ b/mysql-test/suite/backup/t/backup_external_non_win_not_falcon.test 2009-11-13 12:10:39 +0000
@@ -9,6 +9,11 @@
--source suite/backup/include/backup_ext.inc
--source suite/backup/include/have_dbi.inc
+if(`select "$MYSQL_CONVERT_TABLE_FORMAT" NOT LIKE '%convert_table_format%'`)
+{
+--skip Could not find mysql_convert_table_format utility.
+}
+
let $MYSQLD_BACKUPDIR = `select @@backupdir`;
let $MYSQLD_DATADIR= `select @@datadir`;
@@ -69,7 +74,6 @@ INSERT INTO db2.t1(b,c) VALUES
# Changing the storage engine for db1
SHOW CREATE TABLE db1.t1;
-source $MYSQLTEST_VARDIR/tmp/mctf.inc;
--exec $MYSQL_CONVERT_TABLE_FORMAT --user=root -S $MASTER_MYSOCK --port=$MASTER_MYPORT --type=innodb db1
--echo
@@ -90,7 +94,6 @@ RESTORE FROM 'db1.bak';
SHOW CREATE TABLE db1.t1;
--echo # Changing the storage engine back to myisam
-source $MYSQLTEST_VARDIR/tmp/mctf.inc;
--exec $MYSQL_CONVERT_TABLE_FORMAT -u root -S $MASTER_MYSOCK --port=$MASTER_MYPORT db1
SHOW CREATE TABLE db1.t1;
@@ -149,7 +152,6 @@ BACKUP DATABASE db1 TO 'db1.bak';
--echo # tables in db1
--disable_warnings
-source $MYSQLTEST_VARDIR/tmp/mctf.inc;
--exec $MYSQL_CONVERT_TABLE_FORMAT -u root -S $MASTER_MYSOCK --port=$MASTER_MYPORT --type=myisam db1
--enable_warnings
@@ -182,7 +184,6 @@ RESTORE FROM 'db1.bak' OVERWRITE;
SHOW CREATE TABLE db1.t2;
-source $MYSQLTEST_VARDIR/tmp/mctf.inc;
--exec $MYSQL_CONVERT_TABLE_FORMAT -u root -S $MASTER_MYSOCK --port=$MASTER_MYPORT --type=innodb db1
SHOW CREATE TABLE db1.tpl;
@@ -215,7 +216,6 @@ DROP VIEW db2.v1;
--remove_file $MYSQLD_BACKUPDIR/db1.bak
--echo # Changing the storage engine back to myisam after restore
-source $MYSQLTEST_VARDIR/tmp/mctf.inc;
--exec $MYSQL_CONVERT_TABLE_FORMAT -u root -S $MASTER_MYSOCK --port=$MASTER_MYPORT db1
SHOW CREATE TABLE db1.t1;
=== modified file 'mysql-test/suite/backup/t/backup_logs.test'
--- a/mysql-test/suite/backup/t/backup_logs.test 2009-10-12 09:08:34 +0000
+++ b/mysql-test/suite/backup/t/backup_logs.test 2009-11-10 17:24:18 +0000
@@ -289,12 +289,6 @@ connection con1;
SET time_zone='+0:00';
SELECT now() INTO @stop_backup;
---echo We calculate the timedifference between backup start time and stop
---echo time. If this difference is '0', then backup start time and stop time
---echo are same.
-
-SELECT timediff(@stop_backup, @start_backup) > 5;
-
--echo
--echo Now verify actual start time / stop time of backup and start time /
--echo stop time from backup_history table. If the both times are same,
=== modified file 'mysql-test/suite/backup/t/backup_logs_output.test'
--- a/mysql-test/suite/backup/t/backup_logs_output.test 2009-10-26 09:16:48 +0000
+++ b/mysql-test/suite/backup/t/backup_logs_output.test 2009-11-16 15:21:34 +0000
@@ -263,6 +263,54 @@ FLUSH BACKUP LOGS;
--exec $MYSQLADMIN --no-defaults --default-character-set=latin1 -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= flush-backup-logs 2>&1
+#
+# BUG#48353 - add 'purge backup logs' to mysqladmin.
+#
+# 'purge backup logs' reopens log files (PURGE BACKUP LOGS only).
+# Log files are created irrespective of log_backup_output options.
+# Test 'purge-backup-logs' from mysqladmin for log_backup_ouput=TABLE,FILE.
+#
+
+--echo #
+--echo # Test purge-backup-logs from mysqladmin
+--echo #
+--exec $MYSQLADMIN --no-defaults --default-character-set=latin1 -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= purge-backup-logs 2>&1
+
+--echo #
+--echo # Do another backup here then try next version of purge backup logs
+--echo #
+--remove_file $MYSQLD_BACKUPDIR/bup_log.bak
+--replace_column 1 #
+BACKUP DATABASE bup_log TO 'bup_log.bak';
+
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+--echo #
+--echo # Test purge-backup-logs-to from mysqladmin
+--echo #
+--exec $MYSQLADMIN --no-defaults --default-character-set=latin1 -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= purge-backup-logs-id 99999 2>&1
+
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+--echo #
+--echo # Do another backup here then try next version of purge backup logs
+--echo #
+--remove_file $MYSQLD_BACKUPDIR/bup_log.bak
+--replace_column 1 #
+BACKUP DATABASE bup_log TO 'bup_log.bak';
+
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
+
+--echo #
+--echo # Test purge-backup-logs-date from mysqladmin
+--echo #
+--exec $MYSQLADMIN --no-defaults --default-character-set=latin1 -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= purge-backup-logs-date '2024-12-31 23:15:10' 2>&1
+
+SELECT count(*) FROM mysql.backup_history;
+SELECT count(*) FROM mysql.backup_progress;
--file_exists $MYSQLD_DATADIR/backup_history.log
--file_exists $MYSQLD_DATADIR/backup_progress.log
=== modified file 'mysql-test/suite/backup/t/backup_myisam.test'
--- a/mysql-test/suite/backup/t/backup_myisam.test 2009-02-24 20:57:21 +0000
+++ b/mysql-test/suite/backup/t/backup_myisam.test 2009-11-16 19:20:34 +0000
@@ -32,12 +32,20 @@ INSERT INTO mysql_db1.t1 SELECT * FROM m
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
FLUSH TABLE mysql_db1.t1;
#
+--echo # exec myisampack
--exec $MYISAMPACK -s $MYSQLD_DATADIR/mysql_db1/t1
+--echo # exec myisamchk
--exec $MYISAMCHK -srq $MYSQLD_DATADIR/mysql_db1/t1
#
---replace_column 1 #
+--replace_column 1 ###
BACKUP DATABASE mysql_db1 to 'bup_myisam.bak';
---replace_column 1 #
+#
+--echo # RESTORE of a compressed MyISAM table issues two warnings:
+--echo # "Table is read only" and "Deadlock found when trying to get lock".
+--echo # This results from an internal call of FLUSH TABLES.
+--echo # RESTORE can't get back its write lock on the now compressed table.
+--echo # But it doesn't need the locks any more at this moment. So it's ok.
+--replace_column 1 ###
RESTORE FROM 'bup_myisam.bak' OVERWRITE;
#
SELECT COUNT(*) FROM mysql_db1.t1 WHERE c2 < 5;
=== modified file 'mysql-test/suite/backup/t/backup_myisam_coverage.test'
--- a/mysql-test/suite/backup/t/backup_myisam_coverage.test 2009-02-24 20:57:21 +0000
+++ b/mysql-test/suite/backup/t/backup_myisam_coverage.test 2009-11-16 19:20:34 +0000
@@ -33,7 +33,9 @@ INSERT INTO mysql_db1.t1 SELECT * FROM m
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
FLUSH TABLE mysql_db1.t1;
#
+--echo # exec myisampack
--exec $MYISAMPACK -s $MYSQLD_DATADIR/mysql_db1/t1
+--echo # exec myisamchk
--exec $MYISAMCHK -srq $MYSQLD_DATADIR/mysql_db1/t1
#
--replace_column 1 #
@@ -41,6 +43,11 @@ BACKUP DATABASE mysql_db1 to 'bup_myisam
#
# Inject error at Backup_restore_ctx_unlock_tables_alloc
SET debug='d,Backup_restore_ctx_unlock_tables_alloc';
+--echo # RESTORE of a compressed MyISAM table issues two warnings:
+--echo # "Table is read only" and "Deadlock found when trying to get lock".
+--echo # This results from an internal call of FLUSH TABLES.
+--echo # RESTORE can't get back its write lock on the now compressed table.
+--echo # But it doesn't need the locks any more at this moment. So it's ok.
--replace_column 1 #
RESTORE FROM 'bup_myisam3.bak' OVERWRITE;
#
=== modified file 'mysql-test/suite/backup/t/backup_myisam_sync.test'
--- a/mysql-test/suite/backup/t/backup_myisam_sync.test 2009-04-14 13:40:06 +0000
+++ b/mysql-test/suite/backup/t/backup_myisam_sync.test 2009-11-16 19:20:34 +0000
@@ -1,4 +1,7 @@
+#
# Tests specific of MyISAM's online backup.
+# With DEBUG_SYNC.
+#
--source include/not_embedded.inc
--source include/have_debug_sync.inc
@@ -11,6 +14,7 @@
SET DEBUG_SYNC= 'RESET';
USE test;
DROP DATABASE IF EXISTS mysqltest;
+let $MYSQLD_DATADIR= `select @@datadir`;
let $MYSQLD_BACKUPDIR= `SELECT @@backupdir`;
--error 0,1
remove_file $MYSQLD_BACKUPDIR/bup_myisam_sync.bak;
@@ -101,10 +105,77 @@ SELECT SUM(VARIABLE_VALUE) > 0 AS key_ca
--echo
#
-# Cleanup from this test case
+# Cleanup
#
---echo # final cleanup
+--echo # cleanup
USE test;
DROP DATABASE mysqltest;
SET DEBUG_SYNC= 'RESET';
+--echo #
+--echo # Bug#40944 - Backup: crash after myisampack
+--echo # Patch #2
+--echo #
+CREATE DATABASE bup_myisam_sync_db1;
+CREATE TABLE bup_myisam_sync_db1.t1 (c1 VARCHAR(5), c2 int) ENGINE=MyISAM;
+CREATE INDEX i1 ON bup_myisam_sync_db1.t1 (c1, c2);
+INSERT INTO bup_myisam_sync_db1.t1 VALUES ('A',1);
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+FLUSH TABLE bup_myisam_sync_db1.t1;
+#CREATE TABLE bup_myisam_sync_db1.t0 LIKE bup_myisam_sync_db1.t1;
+#CREATE TABLE bup_myisam_sync_db1.t2 LIKE bup_myisam_sync_db1.t1;
+#
+--echo # exec myisampack
+--exec $MYISAMPACK -s $MYSQLD_DATADIR/bup_myisam_sync_db1/t1
+--echo # exec myisamchk
+--exec $MYISAMCHK -srq $MYSQLD_DATADIR/bup_myisam_sync_db1/t1
+#
+--replace_column 1 #
+BACKUP DATABASE bup_myisam_sync_db1 to 'bup_myisam_sync_db1.bak';
+#
+DROP DATABASE bup_myisam_sync_db1;
+#
+SET DEBUG_SYNC= 'after_restore_locks_tables SIGNAL restore_locked
+ WAIT_FOR restore_finish';
+#SET GLOBAL debug='+O,../../log/mysqld.1.trace';
+#SET debug='+d:+t:+i';
+send RESTORE FROM 'bup_myisam_sync_db1.bak';
+#
+ --echo #
+ --echo # connection con1
+ --connect(con1, localhost, root,,)
+ SET DEBUG_SYNC= 'now WAIT_FOR restore_locked';
+ SET DEBUG_SYNC= 'wait_for_lock SIGNAL restore_finish';
+ send SELECT COUNT(*) FROM bup_myisam_sync_db1.t1 WHERE c2 < 5;
+#
+--echo #
+--echo # connection default
+--connection default
+--echo # RESTORE of a compressed MyISAM table issues two warnings:
+--echo # "Table is read only" and "Deadlock found when trying to get lock".
+--echo # This results from an internal call of FLUSH TABLES.
+--echo # RESTORE can't get back its write lock on the now compressed table.
+--echo # But it doesn't need the locks any more at this moment. So it's ok.
+--replace_column 1 ###
+reap;
+#SET debug='-d:-t:-i';
+#
+ --echo #
+ --echo # connection con1
+ --connection con1
+ reap;
+ --disconnect con1
+#
+--echo #
+--echo # connection default
+--connection default
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE bup_myisam_sync_db1;
+--remove_file $MYSQLD_BACKUPDIR/bup_myisam_sync_db1.bak
+
=== modified file 'mysql-test/suite/backup/t/backup_no_engine.test'
--- a/mysql-test/suite/backup/t/backup_no_engine.test 2009-06-18 11:28:01 +0000
+++ b/mysql-test/suite/backup/t/backup_no_engine.test 2009-11-09 10:56:12 +0000
@@ -3,6 +3,10 @@
--source include/not_embedded.inc
+--echo Suppress this error in the server log
+call mtr.add_suppression("Can't access storage engine of table ");
+--echo
+
# .frm file for a table using non-existent storage engine
--let $table_def=$MYSQL_TEST_DIR/std_data/bug30938.frm
@@ -20,21 +24,11 @@ copy_file $table_def $MYSQLD_DATADIR/db/
SHOW TABLES IN db;
-# backup test database, the table with no storage engine will be ignored
+# backup test database, an error will be displayed
+# as storage engine of the table is not identified
--replace_column 1 #
+--error ER_UNKNOWN_STORAGE_ENGINE
BACKUP DATABASE db TO "db.backup";
-
-# wipe-out backed-up database
-DROP DATABASE db;
-
---replace_column 1 #
-RESTORE FROM "db.backup";
-
-# check that the table with no engine was excluded
-SHOW TABLES IN db;
-# check that table t was correctly restored
-SHOW CREATE TABLE db.t1;
-
+SHOW WARNINGS;
# clean up
DROP DATABASE db;
-remove_file $MYSQLD_BACKUPDIR/db.backup;
=== added file 'mysql-test/suite/backup/t/backup_restore_locking.test'
--- a/mysql-test/suite/backup/t/backup_restore_locking.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_restore_locking.test 2009-11-16 19:20:34 +0000
@@ -0,0 +1,201 @@
+#
+# Bug#41716 - Backup Error when sending data (for table #1)
+# to Default/Snapshot restore driver
+#
+# Ingo Struewing, 2009-06-16, test suggested by Guilhem Bichot
+# Ingo Struewing, 2009-07-22, WL#4844
+#
+
+--source include/have_debug_sync.inc
+--source include/not_embedded.inc
+
+call mtr.add_suppression("Restore: Open and lock tables failed in RESTORE");
+
+--echo #
+--echo # Precautionary cleanup
+--echo #
+SET DEBUG_SYNC= 'RESET';
+SET @old_sessiondebug=@@session.debug;
+let $MYSQLD_BACKUPDIR=`select @@backupdir`;
+--disable_warnings
+DROP DATABASE IF EXISTS bup_reslock_db1;
+--error 0,1
+--remove_file $MYSQLD_BACKUPDIR/bup_reslock_db1.bak
+--enable_warnings
+
+--echo #
+--echo # Bug#41716 - Backup Error when sending data (for table #1)
+--echo # to Default/Snapshot restore driver
+--echo #
+CREATE DATABASE bup_reslock_db1;
+USE bup_reslock_db1;
+CREATE TABLE t1 (c1 INT, c2 VARCHAR(100), UNIQUE(c1)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES (1,"abc");
+#
+--replace_column 1 ###
+BACKUP DATABASE bup_reslock_db1 TO 'bup_reslock_db1.bak';
+#
+DROP DATABASE bup_reslock_db1;
+#
+SET DEBUG_SYNC= 'before_restore_locks_tables SIGNAL restore_before_locking
+ WAIT_FOR restore_finish';
+send RESTORE FROM 'bup_reslock_db1.bak';
+#
+ --echo #
+ --echo # connection con1
+ --connect (con1, localhost, root,,)
+ SET DEBUG_SYNC= 'now WAIT_FOR restore_before_locking';
+ INSERT INTO bup_reslock_db1.t1 VALUES(1,"def");
+ SET DEBUG_SYNC= 'now SIGNAL restore_finish';
+ --disconnect con1
+#
+--echo #
+--echo # connection default, retrieve RESTORE result.
+--connection default
+--replace_column 1 ###
+reap;
+SET DEBUG_SYNC= 'RESET';
+#
+SELECT * FROM t1;
+FLUSH TABLE t1;
+SELECT * FROM t1;
+#
+USE test;
+DROP DATABASE bup_reslock_db1;
+--remove_file $MYSQLD_BACKUPDIR/bup_reslock_db1.bak
+
+--echo #
+--echo # WL#4844 - Implement a locking scheme for RESTORE
+--echo #
+CREATE DATABASE bup_reslock_db1;
+USE bup_reslock_db1;
+CREATE TABLE t1 (c1 INT, c2 VARCHAR(100), UNIQUE(c1)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES (0,"backup");
+#
+--replace_column 1 ###
+BACKUP DATABASE bup_reslock_db1 TO 'bup_reslock_db1.bak';
+#
+DROP DATABASE bup_reslock_db1;
+#
+SET DEBUG_SYNC= 'after_restore_lock_tables_for_write
+ SIGNAL waiting WAIT_FOR continue';
+SET DEBUG_SYNC= 'after_restore_truncate_tables
+ SIGNAL waiting WAIT_FOR continue';
+SET DEBUG_SYNC= 'before_restore_flush_tables
+ SIGNAL waiting WAIT_FOR continue';
+SET DEBUG_SYNC= 'before_restore_unlock_tables
+ SIGNAL waiting WAIT_FOR continue';
+send RESTORE FROM 'bup_reslock_db1.bak';
+#
+ --echo #
+ --echo # connection con1
+ --connect (con1, localhost, root,,)
+ SET DEBUG_SYNC= 'now WAIT_FOR waiting';
+ SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+ send INSERT INTO bup_reslock_db1.t1 VALUES(1,"after_lock_tables");
+#
+ --echo #
+ --echo # connection con2
+ --connect (con2, localhost, root,,)
+ SET DEBUG_SYNC= 'now WAIT_FOR lock_wait';
+ SET DEBUG_SYNC= 'now SIGNAL continue WAIT_FOR waiting';
+ SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+ send INSERT INTO bup_reslock_db1.t1 VALUES(2,"after_truncate_tables");
+#
+ --echo #
+ --echo # connection con3
+ --connect (con3, localhost, root,,)
+ SET DEBUG_SYNC= 'now SIGNAL continue WAIT_FOR waiting';
+ SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+ send INSERT INTO bup_reslock_db1.t1 VALUES(3,"before_flush_tables");
+#
+ --echo #
+ --echo # connection con4
+ --connect (con4, localhost, root,,)
+ SET DEBUG_SYNC= 'now WAIT_FOR lock_wait';
+ SET DEBUG_SYNC= 'now SIGNAL continue WAIT_FOR waiting';
+ SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+ send INSERT INTO bup_reslock_db1.t1 VALUES(4,"before_unlock_tables");
+#
+ --echo #
+ --echo # connection con5
+ --connect (con5, localhost, root,,)
+ SET DEBUG_SYNC= 'now WAIT_FOR lock_wait';
+ SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST;
+ SET DEBUG_SYNC= 'now SIGNAL continue';
+ --disconnect con5
+#
+--echo #
+--echo # connection default, retrieve RESTORE result
+--connection default
+--replace_column 1 ###
+reap;
+SET DEBUG_SYNC= 'RESET';
+#
+ --echo #
+ --echo # connection con1, retrieve INSERT result.
+ --connection con1
+ reap;
+ --disconnect con1
+#
+ --echo #
+ --echo # connection con2, retrieve INSERT result.
+ --connection con2
+ reap;
+ --disconnect con2
+#
+ --echo #
+ --echo # connection con3, retrieve INSERT result.
+ --connection con3
+ reap;
+ --disconnect con3
+#
+ --echo #
+ --echo # connection con4, retrieve INSERT result.
+ --connection con4
+ reap;
+ --disconnect con4
+#
+--echo #
+--echo # connection default
+--connection default
+SELECT * FROM t1 ORDER BY c1;
+FLUSH TABLE t1;
+SELECT * FROM t1 ORDER BY c1;
+#
+USE test;
+DROP DATABASE bup_reslock_db1;
+
+--echo #
+--echo # WL#4844 - Implement a locking scheme for RESTORE
+--echo # Code coverage tests.
+--echo #
+SET DEBUG='+d,error_inject_truncate_enter';
+--error ER_BACKUP_OPEN_TABLES
+RESTORE FROM 'bup_reslock_db1.bak';
+SET debug=@old_sessiondebug;
+DROP DATABASE bup_reslock_db1;
+#
+LET $ID=`SELECT CONNECTION_ID()`;
+SET DEBUG_SYNC='after_restore_truncate_tables SIGNAL sync WAIT_FOR go';
+send RESTORE FROM 'bup_reslock_db1.bak';
+#
+ --echo #
+ --echo # connection con1
+ --connect (con1, localhost, root,,)
+ SET DEBUG_SYNC= 'now WAIT_FOR sync';
+ --replace_regex /KILL QUERY [0-9]+/KILL QUERY ##/
+ eval KILL QUERY $ID;
+ SET DEBUG_SYNC= 'now SIGNAL go';
+ --disconnect con1
+#
+--echo #
+--echo # connection default, retrieve RESTORE result.
+--connection default
+--error ER_QUERY_INTERRUPTED
+reap;
+SET DEBUG_SYNC= 'RESET';
+#
+DROP DATABASE bup_reslock_db1;
+--remove_file $MYSQLD_BACKUPDIR/bup_reslock_db1.bak
+
=== modified file 'mysql-test/suite/backup_engines/r/backup_interruption.result'
--- a/mysql-test/suite/backup_engines/r/backup_interruption.result 2009-10-09 13:03:56 +0000
+++ b/mysql-test/suite/backup_engines/r/backup_interruption.result 2009-11-17 20:18:50 +0000
@@ -196,8 +196,6 @@ SHOW WARNINGS;
Level Code Message
Error <error-code> Query execution was interrupted
Error <error-code> Query execution was interrupted
-Error <error-code> Query execution was interrupted
-Error <error-code> Query execution was interrupted
Warning <error-code> Operation aborted
#
# Examine backup logs.
@@ -414,8 +412,6 @@ SHOW WARNINGS;
Level Code Message
Error <error-code> Query execution was interrupted
Error <error-code> Query execution was interrupted
-Error <error-code> Query execution was interrupted
-Error <error-code> Query execution was interrupted
Warning <error-code> Operation aborted
#
# Examine backup logs.
@@ -1412,6 +1408,7 @@ ERROR 70100: Query execution was interru
SHOW WARNINGS;
Level Code Message
Error <error-code> Query execution was interrupted
+Error <error-code> Query execution was interrupted
Warning <error-code> Operation aborted - data might be corrupted
#
# Examine backup logs.
@@ -1456,6 +1453,7 @@ ERROR 70100: Query execution was interru
SHOW WARNINGS;
Level Code Message
Error <error-code> Query execution was interrupted
+Error <error-code> Query execution was interrupted
Warning <error-code> Operation aborted - data might be corrupted
#
# Examine backup logs.
@@ -1500,6 +1498,7 @@ ERROR 70100: Query execution was interru
SHOW WARNINGS;
Level Code Message
Error <error-code> Query execution was interrupted
+Error <error-code> Query execution was interrupted
Warning <error-code> Operation aborted - data might be corrupted
#
# Examine backup logs.
@@ -1544,6 +1543,7 @@ ERROR 70100: Query execution was interru
SHOW WARNINGS;
Level Code Message
Error <error-code> Query execution was interrupted
+Error <error-code> Query execution was interrupted
Warning <error-code> Operation aborted - data might be corrupted
#
# Examine backup logs.
@@ -1588,6 +1588,7 @@ ERROR 70100: Query execution was interru
SHOW WARNINGS;
Level Code Message
Error <error-code> Query execution was interrupted
+Error <error-code> Query execution was interrupted
Warning <error-code> Operation aborted - data might be corrupted
#
# Examine backup logs.
@@ -1632,6 +1633,7 @@ ERROR 70100: Query execution was interru
SHOW WARNINGS;
Level Code Message
Error <error-code> Query execution was interrupted
+Error <error-code> Query execution was interrupted
Warning <error-code> Operation aborted - data might be corrupted
#
# Examine backup logs.
@@ -1676,6 +1678,7 @@ ERROR 70100: Query execution was interru
SHOW WARNINGS;
Level Code Message
Error <error-code> Query execution was interrupted
+Error <error-code> Query execution was interrupted
Warning <error-code> Operation aborted - data might be corrupted
#
# Examine backup logs.
=== modified file 'sql/backup/backup_info.cc'
--- a/sql/backup/backup_info.cc 2009-11-18 16:47:46 +0000
+++ b/sql/backup/backup_info.cc 2009-11-18 17:30:09 +0000
@@ -729,7 +729,18 @@ backup::Image_info::Db* Backup_info::add
}
// Check to see if the user can see all of the objects in the database.
- if (obs::check_user_access(m_thd, name))
+ bool has_access= FALSE;
+ bool got_error= obs::check_user_access(m_thd, name, &has_access);
+
+ DBUG_EXECUTE_IF("ER_BACKUP_USER_PRIV_CHECK_add_db", got_error= TRUE;);
+
+ if (got_error)
+ {
+ m_log.report_error(ER_BACKUP_USER_PRIV_CHECK, m_thd->security_ctx->user);
+ return NULL;
+ }
+
+ if (!has_access)
{
m_log.report_error(ER_BACKUP_ACCESS_OBJS_INCOMPLETE, name->ptr());
return NULL;
@@ -857,7 +868,18 @@ int Backup_info::add_all_dbs()
int res= 0;
// Check to see if the user can see all of the databases.
- if (check_user_access(m_thd, 0))
+ bool has_access= FALSE;
+ bool got_error= obs::check_user_access(m_thd, 0, &has_access);
+
+ DBUG_EXECUTE_IF("ER_BACKUP_USER_PRIV_CHECK_add_all_dbs", got_error= TRUE;);
+
+ if (got_error)
+ {
+ m_log.report_error(ER_BACKUP_USER_PRIV_CHECK, m_thd->security_ctx->user);
+ return ERROR;
+ }
+
+ if (!has_access)
{
m_log.report_error(ER_BACKUP_ACCESS_DBS_INCOMPLETE);
return ERROR;
=== modified file 'sql/backup/kernel.cc'
--- a/sql/backup/kernel.cc 2009-10-23 15:41:56 +0000
+++ b/sql/backup/kernel.cc 2009-11-17 20:18:50 +0000
@@ -249,7 +249,7 @@ execute_backup_command(THD *thd,
/* Error condition insertion for ER_BACKUP_BACKUP_PREPARE. */
DBUG_EXECUTE_IF("ER_BACKUP_BACKUP_PREPARE_2", res= 1;);
- if (res || !info->is_valid())
+ if (context.report_killed() || res || !info->is_valid())
DBUG_RETURN(send_error(context, ER_BACKUP_BACKUP_PREPARE));
int count= info->db_count();
@@ -347,7 +347,17 @@ execute_backup_command(THD *thd,
static
int send_error(Backup_restore_ctx &context, int error_code, ...)
{
- if (!context.is_killed() && !context.error_reported())
+ using namespace backup;
+
+ /* Atmost one error should be reported. */
+ if (context.error_reported())
+ return error_code;
+
+ /* Report error state if not already done. */
+ context.report_state(BUP_ERRORS);
+
+ /* If the query has been interrupted, do not print this message. */
+ if (!context.is_killed())
{
char buf[MYSQL_ERRMSG_SIZE];
va_list args;
@@ -1097,14 +1107,26 @@ int Backup_restore_ctx::lock_tables_for_
}
}
- DBUG_EXECUTE_IF("restore_lock_tables_for_restore",
- /*
- Mimic error in opening tables. Cannot be done by setting ret=1
- after open_and_lock_tables_derived becase that method is
- supposed to release the lock before returning error.
- */
- return fatal_error(report_error(ER_BACKUP_OPEN_TABLES,"RESTORE"));
- );
+ ret= obs::lock_tables_for_write(m_thd, m_backup_tables);
+ if (ret)
+ goto err1;
+ DEBUG_SYNC(m_thd, "after_restore_lock_tables_for_write");
+
+ /*
+ Truncate tables. Some INSERT might have found the freshly
+ created table.
+ */
+ ret= obs::truncate_tables(m_thd, m_backup_tables);
+ if (ret)
+ goto err;
+ DEBUG_SYNC(m_thd, "after_restore_truncate_tables");
+
+ /*
+ Mimic error in opening tables. Cannot be done by setting ret=1
+ after open_and_lock_tables_derived becase that method is
+ supposed to release the lock before returning error.
+ */
+ DBUG_EXECUTE_IF("restore_lock_tables_for_restore", goto err;);
/*
Open and lock the tables.
@@ -1121,10 +1143,15 @@ int Backup_restore_ctx::lock_tables_for_
/* Do not open tmp tables. */
);
if (ret || is_killed())
- return fatal_error(report_error(ER_BACKUP_OPEN_TABLES,"RESTORE"));
+ goto err;
m_tables_locked= TRUE;
return 0;
+
+ err:
+ (void) obs::unlock_tables(m_thd);
+ err1:
+ return fatal_error(report_error(ER_BACKUP_OPEN_TABLES, "RESTORE"));
}
@@ -1139,26 +1166,26 @@ void Backup_restore_ctx::unlock_tables()
return;
DBUG_PRINT("restore",("unlocking tables"));
+ close_thread_tables(m_thd); // Never errors.
+ m_tables_locked= FALSE;
/*
Refresh tables that have been restored. Some restore drivers might
restore a table layout that differs from the version created by
- materialize(). We need to force a final close after restore with
- close_cached_tables(). Note that we do this before we unlock the
- tables. Otherwise other threads could use the still open tables
- before we refresh them.
+ materialize(). We need to force a final close after restore.
For information about a concrete problem, see the comment in
myisam_backup_engine.cc:Table_restore::close().
Use the restore table list as created by lock_tables_for_restore().
- */
- if (m_backup_tables)
- close_cached_tables(m_thd, m_backup_tables, FALSE, FALSE);
-
- close_thread_tables(m_thd); // Never errors.
- m_tables_locked= FALSE;
+ We ignore the status from FLUSH and UNLOCK as there is no way
+ to deal with such problems here.
+ */
+ DEBUG_SYNC(m_thd, "before_restore_flush_tables");
+ (void) obs::flush_tables(m_thd, m_backup_tables);
+ DEBUG_SYNC(m_thd, "before_restore_unlock_tables");
+ (void) obs::unlock_tables(m_thd);
return;
}
=== modified file 'sql/backup/logger.h'
--- a/sql/backup/logger.h 2009-10-21 13:32:24 +0000
+++ b/sql/backup/logger.h 2009-11-17 20:18:50 +0000
@@ -263,7 +263,7 @@ void Logger::report_start(time_t when)
report_error(log_level::INFO, m_type == BACKUP ? ER_BACKUP_BACKUP_START
: ER_BACKUP_RESTORE_START);
backup_log->start(when);
- backup_log->state(BUP_RUNNING);
+ backup_log->set_state(BUP_RUNNING);
}
@@ -329,21 +329,23 @@ void Logger::report_aborted(time_t when,
/**
- Report change of the state of operation
+ Report current state of operation only when there is state change.
+ This can be called multiple times without generating duplicate messages.
For possible states see definition of @c enum_backup_state
@todo Consider reporting state changes in the server error log (as info
entries).
+
*/
inline
void Logger::report_state(enum_backup_state state)
{
- DBUG_ASSERT(m_state == RUNNING || m_state == READY);
- DBUG_ASSERT(backup_log);
-
- backup_log->state(state);
+ if (!backup_log)
+ return;
+ if (backup_log->get_state() != state)
+ backup_log->set_state(state);
}
@@ -443,7 +445,7 @@ int Logger::init(enum_type type, const c
m_type= type;
backup_log = new Backup_log(m_thd, (enum_backup_operation)type, query);
- backup_log->state(BUP_STARTING);
+ backup_log->set_state(BUP_STARTING);
m_state= READY;
DEBUG_SYNC(m_thd, "after_backup_log_init");
return 0;
=== modified file 'sql/backup/stream_v1_transport.c'
--- a/sql/backup/stream_v1_transport.c 2009-10-22 08:08:43 +0000
+++ b/sql/backup/stream_v1_transport.c 2009-11-16 07:36:42 +0000
@@ -2022,7 +2022,7 @@ int bstream_next_chunk(backup_stream *s)
empty the buffer so that the next fragment will be loaded into it when
the buffer is re-filled below.
*/
- if (s->buf.header < s->buf.pos)
+ if (s->buf.header <= s->buf.pos)
s->buf.begin= s->buf.header;
else
{
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2009-10-26 14:02:26 +0000
+++ b/sql/log.cc 2009-11-16 18:37:18 +0000
@@ -3936,10 +3936,73 @@ bool MYSQL_BACKUP_LOG::write(THD *thd, s
goto err;
if (write_str(history_data->binlog_file))
goto err;
- if (write_int(history_data->state))
+
+ /*
+ Print the enumerated values to match the columns in the
+ table.
+ */
+ switch (history_data->state) {
+ case BUP_COMPLETE:
+ {
+ if (write_str("complete"))
+ goto err;
+ break;
+ }
+ case BUP_STARTING:
+ {
+ if (write_str("starting"))
+ goto err;
+ break;
+ }
+ case BUP_VALIDITY_POINT:
+ {
+ if (write_str("validity point"))
+ goto err;
+ break;
+ }
+ case BUP_RUNNING:
+ {
+ if (write_str("running"))
+ goto err;
+ break;
+ }
+ case BUP_ERRORS:
+ {
+ if (write_str("error"))
+ goto err;
+ break;
+ }
+ case BUP_CANCEL:
+ {
+ if (write_str("cancel"))
+ goto err;
+ break;
+ }
+ default: // Should be no other values.
goto err;
- if (write_int(history_data->operation))
+ }
+
+ /*
+ Print the enumerated values to match the columns in the
+ table.
+ */
+ switch (history_data->operation) {
+ case OP_BACKUP:
+ {
+ if (write_str("backup"))
+ goto err;
+ break;
+ }
+ case OP_RESTORE:
+ {
+ if (write_str("restore"))
+ goto err;
+ break;
+ }
+ default: // Should be no other values.
goto err;
+ }
+
if (write_int(history_data->error_num))
goto err;
if (write_int(history_data->num_objects))
=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt 2009-10-12 09:08:34 +0000
+++ b/sql/share/errmsg-utf8.txt 2009-11-17 20:18:50 +0000
@@ -6562,3 +6562,5 @@ ER_BACKUP_ACCESS_OBJS_INCOMPLETE
eng "Insufficient privileges. You do not have privileges to backup database '%s'."
ER_WARN_I_S_SKIPPED_TABLE
eng "Table '%s'.'%s' was skipped since its definition is being modified by concurrent DDL statement."
+ER_BACKUP_USER_PRIV_CHECK
+ eng "Failed to perform access privileges check for user '%s'."
=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt 2009-10-26 14:02:26 +0000
+++ b/sql/share/errmsg.txt 2009-11-17 20:18:50 +0000
@@ -6562,3 +6562,5 @@ ER_BACKUP_ACCESS_OBJS_INCOMPLETE
eng "Insufficient privileges. You do not have privileges to backup database '%s'."
ER_WARN_I_S_SKIPPED_TABLE
eng "Table '%s'.'%s' was skipped since its definition is being modified by concurrent DDL statement."
+ER_BACKUP_USER_PRIV_CHECK
+ eng "Failed to perform access privileges check for user '%s'."
=== modified file 'sql/si_logs.cc'
--- a/sql/si_logs.cc 2009-05-21 13:17:37 +0000
+++ b/sql/si_logs.cc 2009-11-17 20:18:50 +0000
@@ -162,13 +162,24 @@ bool Backup_log::write_master_binlog_inf
@todo Consider reporting state changes in the server error log (as info
entries).
*/
-void Backup_log::state(enum_backup_state state)
+void Backup_log::set_state(enum_backup_state state)
{
m_op_hist.state= state;
logger.backup_progress_log_write(m_thd, m_op_hist.backup_id, "backup kernel", 0,
0, 0, 0, 0, get_state_string(state));
}
+/**
+ Get current state of operation.
+
+ For possible states see definition of @c enum_backup_state
+ */
+enum_backup_state Backup_log::get_state()
+{
+ return m_op_hist.state;
+}
+
+
/**
Report validity point creation time.
=== modified file 'sql/si_logs.h'
--- a/sql/si_logs.h 2009-05-21 13:17:37 +0000
+++ b/sql/si_logs.h 2009-11-17 20:18:50 +0000
@@ -10,27 +10,30 @@
/**
List of operations for backup history log.
+
+ @note These must match the definition for the column 'operation'
+ in the backup_history and backup_progress tables.
*/
enum enum_backup_operation
{
OP_BACKUP = 1,
- OP_RESTORE,
- OP_SHOW,
- OP_OTHER
+ OP_RESTORE = 2
};
/**
List of states for backup logs.
+
+ @note These must match the definition for the column 'backup_state'
+ in the backup_history table.
*/
enum enum_backup_state
{
- BUP_UNKNOWN = 0,
- BUP_COMPLETE,
- BUP_STARTING,
- BUP_VALIDITY_POINT,
- BUP_RUNNING,
- BUP_ERRORS,
- BUP_CANCEL
+ BUP_COMPLETE = 1,
+ BUP_STARTING = 2,
+ BUP_VALIDITY_POINT = 3,
+ BUP_RUNNING = 4,
+ BUP_ERRORS = 5,
+ BUP_CANCEL = 6
};
/**
@@ -130,7 +133,8 @@ public:
the backup_history log.
*/
ulonglong get_backup_id() { return m_op_hist.backup_id; }
- void state(enum_backup_state);
+ void set_state(enum_backup_state);
+ enum_backup_state get_state();
void error_num(int code) { m_op_hist.error_num= code; }
void binlog_start_pos(unsigned long int pos)
{
=== modified file 'sql/si_objects.cc'
--- a/sql/si_objects.cc 2009-11-04 14:18:21 +0000
+++ b/sql/si_objects.cc 2009-11-18 15:27:51 +0000
@@ -180,22 +180,18 @@ void Si_session_context::restore_si_ctx(
///////////////////////////////////////////////////////////////////////////
/**
- Execute one DML statement in a backup-specific context. Result set and
- warning information are stored in the output parameter. Some session
- attributes are preserved and reset to predefined values before query
- execution (@see Si_session_context).
-
- @note This method will temporarily invoke additional privileges for
- all SELECT or SHOW CREATE statements.
+ Execute one SQL statement in a backup-specific context.
- @param[in] thd Thread context.
- @param[in] query SQL query to be executed.
- @param[in] get_warnings If true, copy warnings to the error stack
- @param[out] ed_connection A place to store result and warnings.
+ Some session attributes are preserved and reset to predefined values
+ before query execution (@see Si_session_context).
- @return Error status.
- @retval TRUE on error.
- @retval FALSE on success.
+ @param[in] thd thread handle
+ @param[in] ed_connection Ed_connection handle
+ @param[in] query SQL query to be executed
+
+ @return status
+ @retval TRUE error
+ @retval FALSE success
*/
bool
@@ -1310,11 +1306,6 @@ Iterator *create_row_set_iterator(THD *t
if (run_service_interface_sql(thd, &ed_connection, query, TRUE))
/* Query failed with an error */
return NULL;
- else if(ed_connection.get_warn_count())
- /* Push warnings to BACKUP's error stack. Calling method will
- decide if the warnings are a problem later when serializing the
- object. */
- thd->warning_info->append_warnings(thd, ed_connection.get_warn_list());
DBUG_ASSERT(ed_connection.get_field_count());
@@ -2561,9 +2552,9 @@ Obj_iterator *get_databases(THD *thd)
@param[in] THD Current thread
- @return uint Number of databases.
+ @return int Number of databases. Return value of -1 indicates failure.
*/
-uint get_num_dbs(THD *thd)
+int get_num_dbs(THD *thd)
{
Ed_connection ed_connection(thd);
Ed_result_set *ed_result_set;
@@ -2578,10 +2569,7 @@ uint get_num_dbs(THD *thd)
if (run_service_interface_sql(thd, &ed_connection,
s_stream.lex_string(), TRUE))
/* Query failed with an error */
- return NULL;
- else if(ed_connection.get_warn_count())
- /* Push warnings to BACKUP's error stack. */
- thd->warning_info->append_warnings(thd, ed_connection.get_warn_list());
+ return -1;
DBUG_ASSERT(ed_connection.get_field_count());
@@ -2607,9 +2595,9 @@ uint get_num_dbs(THD *thd)
@param[in] THD Current thread
@param[in] String Database name.
- @return uint Number of objects in the database.
+ @return int Number of objects in the database. Value of -1 means failure.
*/
-uint get_num_objects(THD *thd, const String *db_name)
+int get_num_objects(THD *thd, const String *db_name)
{
Ed_connection ed_connection(thd);
Ed_result_set *ed_result_set;
@@ -2635,10 +2623,7 @@ uint get_num_objects(THD *thd, const Str
if (run_service_interface_sql(thd, &ed_connection,
s_stream.lex_string(), TRUE))
/* Query failed with an error */
- return NULL;
- else if(ed_connection.get_warn_count())
- /* Push warnings to BACKUP's error stack. */
- thd->warning_info->append_warnings(thd, ed_connection.get_warn_list());
+ return -1;
DBUG_ASSERT(ed_connection.get_field_count());
@@ -2650,10 +2635,13 @@ uint get_num_objects(THD *thd, const Str
}
///////////////////////////////////////////////////////////////////////////
-bool check_user_access(THD *thd, const String *db_name)
+bool check_user_access(THD *thd, const String *db_name, bool *has_access)
{
- uint elev_count;
- uint user_count;
+ int elev_count;
+ int user_count;
+
+ DBUG_ASSERT(has_access);
+ *has_access= false; /* Reset access status. */
/*
Get value from user context without elevation.
@@ -2663,6 +2651,9 @@ bool check_user_access(THD *thd, const S
else
user_count= get_num_objects(thd, db_name);
+ if (user_count < 0)
+ return TRUE; /* Return error status */
+
/*
Peform global elevation with SELECT to get value of
someone with global SELECT (e.g. root).
@@ -2682,22 +2673,41 @@ bool check_user_access(THD *thd, const S
thd->security_ctx->master_access= saved_master_access;
thd->security_ctx->db_access= saved_db_access;
- /*
- Compare results and return.
- */
- return !(user_count == elev_count);
+ if (elev_count < 0)
+ return TRUE; /* Return error status */
+
+ /* User has proper access if both counts are same. */
+ *has_access= (user_count == elev_count);
+
+ return FALSE;
}
///////////////////////////////////////////////////////////////////////////
Obj_iterator *get_db_tables(THD *thd, const String *db_name)
{
String_stream s_stream;
+ /*
+ BUG#45587: Backup of tables using a non-existent storage engine
+ does not give warning/error
+ BUG#47697: Inconsistencies in the query outputs on
+ INFORMATION_SCHEMA.TABLES
+
+ Once BUG#47697 is fixed, the query s_stream should be reverted
+ to following query:
+ s_stream<<
+ "SELECT '" << db_name << "', table_name "
+ "FROM INFORMATION_SCHEMA.TABLES "
+ "WHERE table_schema = '" << db_name << "' AND "
+ "table_type = 'BASE TABLE'";
+ */
s_stream <<
- "SELECT '" << db_name << "', table_name "
+ "SELECT '" << db_name << "', table_name "
+ "FROM ( SELECT * "
"FROM INFORMATION_SCHEMA.TABLES "
"WHERE table_schema = '" << db_name << "' AND "
- "table_type = 'BASE TABLE'";
+ "table_type = 'BASE TABLE'"
+ ") AS get_table";
return create_row_set_iterator<Db_tables_iterator>(thd, s_stream.lex_string());
}
@@ -2735,9 +2745,15 @@ Obj_iterator *get_db_stored_procedures(T
String_stream s_stream;
s_stream <<
"SELECT '" << db_name << "', routine_name "
- "FROM INFORMATION_SCHEMA.ROUTINES "
- "WHERE routine_schema COLLATE utf8_bin = '" << db_name << "' AND "
- "routine_type = 'PROCEDURE'";
+ "FROM INFORMATION_SCHEMA.ROUTINES ";
+ /*
+ We need to use case insensitive compare when LCTN = 2 and on Windows.
+ */
+ if ((lower_case_table_names == 2) && IF_WIN(1,0))
+ s_stream << "WHERE routine_schema COLLATE utf8_general_ci = '" << db_name;
+ else
+ s_stream << "WHERE routine_schema COLLATE utf8_bin = '" << db_name;
+ s_stream << "' AND routine_type = 'PROCEDURE'";
return create_row_set_iterator<Db_stored_proc_iterator>(thd, s_stream.lex_string());
}
@@ -2749,9 +2765,15 @@ Obj_iterator *get_db_stored_functions(TH
String_stream s_stream;
s_stream <<
"SELECT '" << db_name << "', routine_name "
- "FROM INFORMATION_SCHEMA.ROUTINES "
- "WHERE routine_schema COLLATE utf8_bin = '" << db_name <<"' AND "
- "routine_type = 'FUNCTION'";
+ "FROM INFORMATION_SCHEMA.ROUTINES ";
+ /*
+ We need to use case insensitive compare when LCTN = 2 and on Windows.
+ */
+ if ((lower_case_table_names == 2) && IF_WIN(1,0))
+ s_stream << "WHERE routine_schema COLLATE utf8_general_ci = '" << db_name;
+ else
+ s_stream << "WHERE routine_schema COLLATE utf8_bin = '" << db_name;
+ s_stream << "' AND routine_type = 'FUNCTION'";
return create_row_set_iterator<Db_stored_func_iterator>(thd, s_stream.lex_string());
}
@@ -2764,8 +2786,14 @@ Obj_iterator *get_db_events(THD *thd, co
String_stream s_stream;
s_stream <<
"SELECT '" << db_name << "', event_name "
- "FROM INFORMATION_SCHEMA.EVENTS "
- "WHERE event_schema COLLATE utf8_bin = '" << db_name <<"'";
+ "FROM INFORMATION_SCHEMA.EVENTS ";
+ /*
+ We need to use case insensitive compare when LCTN = 2 and on Windows.
+ */
+ if ((lower_case_table_names == 2) && IF_WIN(1,0))
+ s_stream << "WHERE event_schema COLLATE utf8_general_ci = '" << db_name << "'";
+ else
+ s_stream << "WHERE event_schema COLLATE utf8_bin = '" << db_name <<"'";
return create_row_set_iterator<Db_event_iterator>(thd, s_stream.lex_string());
#else
@@ -3399,6 +3427,150 @@ int Name_locker::release_name_locks()
///////////////////////////////////////////////////////////////////////////
//
+// Miscellaneous.
+//
+
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ Acquire locks on a list of tables.
+
+ @param[in] thd current thread
+ @param[in] table_list list of tables to lock for write
+
+ @return status
+ @retval FALSE success
+ @retval TRUE error
+*/
+
+bool lock_tables_for_write(THD *thd, TABLE_LIST *table_list)
+{
+ Ed_connection ed_connection(thd);
+ String_stream s_stream;
+ TABLE_LIST *tlist;
+ bool error_status= FALSE;
+ DBUG_ENTER("obs:lock_tables_for_write");
+
+ if (table_list)
+ {
+ s_stream << "LOCK TABLE ";
+ for (tlist= table_list; tlist; tlist= tlist->next_global)
+ {
+ if (tlist != table_list)
+ s_stream << ", ";
+ s_stream << "`" << tlist->db << "`.`" << tlist->table_name << "` WRITE";
+ }
+
+ error_status= run_service_interface_sql(thd, &ed_connection,
+ s_stream.lex_string(), TRUE);
+ }
+ DBUG_RETURN(error_status);
+}
+
+
+/**
+ Release all table locks of this thread.
+
+ @param[in] thd current thread
+
+ @return status
+ @retval FALSE success
+ @retval TRUE error
+*/
+
+bool unlock_tables(THD *thd)
+{
+ Ed_connection ed_connection(thd);
+ String_stream s_stream;
+ bool error_status;
+ DBUG_ENTER("obs:unlock_tables");
+
+ s_stream << "UNLOCK TABLES";
+ error_status= run_service_interface_sql(thd, &ed_connection,
+ s_stream.lex_string(), TRUE);
+ DBUG_RETURN(error_status);
+}
+
+
+/**
+ Flush a list of tables.
+
+ @param[in] thd current thread
+ @param[in] table_list list of tables to flush
+
+ @return status
+ @retval FALSE success
+ @retval TRUE error
+*/
+
+bool flush_tables(THD *thd, TABLE_LIST *table_list)
+{
+ Ed_connection ed_connection(thd);
+ String_stream s_stream;
+ TABLE_LIST *tlist;
+ bool error_status= FALSE;
+ DBUG_ENTER("obs:flush_tables");
+
+ for (tlist= table_list; tlist; tlist= tlist->next_global)
+ {
+ s_stream.reset();
+ s_stream << "FLUSH TABLE ";
+ s_stream << "`" << tlist->db << "`.`" << tlist->table_name << "`";
+ if (run_service_interface_sql(thd, &ed_connection,
+ s_stream.lex_string(), TRUE))
+ {
+ error_status= TRUE;
+ DBUG_PRINT("error", ("execute direct: '%s' errno: %d",
+ s_stream.lex_string()->str,
+ ed_connection.get_last_errno()));
+ }
+ }
+
+ DBUG_RETURN(error_status);
+}
+
+
+/**
+ Truncate a list of tables.
+
+ @param[in] thd current thread
+ @param[in] table_list list of tables to truncate
+
+ @return status
+ @retval FALSE success
+ @retval TRUE error
+*/
+
+bool truncate_tables(THD *thd, TABLE_LIST *table_list)
+{
+ Ed_connection ed_connection(thd);
+ String_stream s_stream;
+ TABLE_LIST *tlist;
+ DBUG_ENTER("obs:truncate_tables");
+
+ /* Allow to execute DDL operations. */
+ ::obs::bml_exception_on(thd);
+
+ for (tlist= table_list; tlist; tlist= tlist->next_global)
+ {
+ s_stream.reset();
+ s_stream << "TRUNCATE TABLE ";
+ s_stream << "`" << tlist->db << "`.`" << tlist->table_name << "`";
+ if (run_service_interface_sql(thd, &ed_connection,
+ s_stream.lex_string(), TRUE))
+ DBUG_RETURN(TRUE);
+ }
+
+ /* Disable further DDL execution. */
+ ::obs::bml_exception_off(thd);
+
+ DBUG_RETURN(FALSE);
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+
+//
// Implementation: Replication methods.
//
=== modified file 'sql/si_objects.h'
--- a/sql/si_objects.h 2009-11-04 14:18:21 +0000
+++ b/sql/si_objects.h 2009-11-17 20:18:50 +0000
@@ -185,18 +185,17 @@ Obj_iterator *get_databases(THD *thd);
2) If db_name != 0, the method shall check the user's visibility for all
objects in the database specified.
- @param[in] THD The current thread.
- @param[in] String The database name to check or 0
-
- @returns Information whether user can see all specified objects
- @retval TRUE
- if db_name != 0 : user does not have visibility to the database specified
- if db_name == 0 : user does not have visibility to all databases
- @retval FALSE
- if db_name != 0 : user does have visibility to the database specified
- if db_name == 0 : user does have visibility to all databases
+ @param[in] THD the current thread
+ @param[in] String the database name to check
+ @param[out] bool set to true/false as described below:
+ TRUE : User has the required access permission
+ FALSE : User does not have the required access permission
+
+ @return boolean value which indicates if an error has occured.
+ @retval TRUE indicates error
+ @retval FALSE indicates success
*/
-bool check_user_access(THD *thd, const String *db_name);
+bool check_user_access(THD *thd, const String *db_name, bool *has_access);
/**
Create an iterator over all base tables in a particular database.
@@ -513,6 +512,20 @@ private:
///////////////////////////////////////////////////////////////////////////
//
+// Miscellaneous.
+//
+
+///////////////////////////////////////////////////////////////////////////
+
+bool lock_tables_for_write(THD *thd, TABLE_LIST *table_list);
+bool unlock_tables(THD *thd);
+bool flush_tables(THD *thd, TABLE_LIST *table_list);
+bool truncate_tables(THD *thd, TABLE_LIST *table_list);
+
+
+///////////////////////////////////////////////////////////////////////////
+
+//
// Replication methods.
//
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2009-10-25 13:41:27 +0000
+++ b/sql/sql_base.cc 2009-11-17 15:17:00 +0000
@@ -1073,7 +1073,8 @@ err_with_reopen:
old locks. This should always succeed (unless some external process
has removed the tables)
*/
- thd->locked_tables_list.reopen_tables(thd);
+ if (thd->locked_tables_list.reopen_tables(thd))
+ result= TRUE;
/*
Since downgrade_exclusive_lock() won't do anything with shared
metadata lock it is much simpler to go through all open tables rather
=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc 2009-10-23 06:24:37 +0000
+++ b/sql/sql_delete.cc 2009-11-16 19:20:34 +0000
@@ -1129,6 +1129,10 @@ bool mysql_truncate(THD *thd, TABLE_LIST
Ha_global_schema_lock_guard global_schema_lock_guard(thd);
DBUG_ENTER("mysql_truncate");
+ DBUG_EXECUTE_IF("error_inject_truncate_enter",
+ my_error(ER_UNKNOWN_ERROR, MYF(0));
+ DBUG_RETURN(TRUE););
+
mysql_ha_rm_tables(thd, table_list);
bzero((char*) &create_info,sizeof(create_info));
=== modified file 'unittest/backup/bstr_callback_errors-t.c'
--- a/unittest/backup/bstr_callback_errors-t.c 2009-10-23 06:24:37 +0000
+++ b/unittest/backup/bstr_callback_errors-t.c 2009-11-16 07:36:42 +0000
@@ -30,14 +30,21 @@ void run_test()
{
uint i;
uint planned;
+ uint read_planned, write_planned;
+
+ write_planned= 1 + global_count + 4 + db_count
+ + 1 + global_count + perdb_count;
+
+ read_planned= 3 + global_count + perdb_count + 2;
+
+ planned = read_planned+write_planned;
+
+ plan(planned);
init_catalog(&img_header);
diag("Testing callback failures during writing of backup image");
- planned= 1 + global_count + 4 + db_count
- + 1 + global_count + perdb_count + 1;
-
/*
Do a clean write of backup image to fill callback_counts structure holding
counters for callback functions.
@@ -89,7 +96,6 @@ void run_test()
diag("Testing callback failures during reading of backup image");
- planned+= 3 + global_count + perdb_count + 2;
/* Do a clean read of the backup image to set the callback counters. */
reset_counts();
@@ -124,8 +130,6 @@ void run_test()
/* test errors in memory allocation */
ok(fail_alloc(RD), "Errors in memory allocation");
- /* Plan (1..n) must be at the beginning or end of the TAP output. */
- plan(planned);
}
=== modified file 'unittest/backup/bstr_eos-t.c'
--- a/unittest/backup/bstr_eos-t.c 2009-10-12 09:08:34 +0000
+++ b/unittest/backup/bstr_eos-t.c 2009-11-16 07:36:42 +0000
@@ -60,6 +60,10 @@ void run_test()
image_header hdr;
int i;
byte header;
+ /*
+ Number of tests to be planned are not known at this point.
+ */
+ plan(NO_PLAN);
init_catalog(&hdr);
@@ -135,8 +139,6 @@ void run_test()
*chunk[i]= header;
}
- /* Plan (1..n) must be at the beginning or end of the TAP output. */
- plan(1 + 2*chunk_count + 3*(chunk_count-3));
}
=== modified file 'unittest/backup/bstr_io_errors-t.c'
--- a/unittest/backup/bstr_io_errors-t.c 2009-10-12 09:08:34 +0000
+++ b/unittest/backup/bstr_io_errors-t.c 2009-11-16 07:36:42 +0000
@@ -16,7 +16,11 @@ void run_test()
{
int i;
int can_pass;
- uint planned;
+
+ /*
+ Number of tests to be planned are not known at this point.
+ */
+ plan(NO_PLAN);
init_catalog(&img_header);
@@ -29,7 +33,6 @@ void run_test()
diag("Made %lu write calls", io_counts.write);
diag("Wrote %lu bytes", (long unsigned)io_counts.write_bytes);
- planned= 1 + 2*io_counts.write;
/*
Errors during last 2 write calls (which happen during closing of a stream)
@@ -61,7 +64,6 @@ void run_test()
diag("Made %lu read calls", io_counts.read);
diag("Read %lu bytes", (long unsigned)io_counts.read_bytes);
- planned+= 1 + io_counts.read;
for(i= io_counts.read; i > 0 ; --i)
{
@@ -71,7 +73,4 @@ void run_test()
"Failing %d-th read call", i);
}
- /* Plan (1..n) must be at the beginning or end of the TAP output. */
- plan(planned);
}
-
=== modified file 'unittest/backup/bstr_random_chunks-t.c'
--- a/unittest/backup/bstr_random_chunks-t.c 2009-10-12 09:08:34 +0000
+++ b/unittest/backup/bstr_random_chunks-t.c 2009-11-16 07:36:42 +0000
@@ -44,9 +44,12 @@ void run_test()
size_t byte_count;
size_t csize;
int ret;
- uint planned;
stream_block_size= BSIZE;
+ /*
+ Number of tests to be planned are not known at this point.
+ */
+ plan(NO_PLAN);
diag("Writing");
@@ -79,7 +82,6 @@ void run_test()
diag("Reading");
- planned= 2*chunk_count + 2;
ret= backup_stream_open_rd(&stream, "random.bst");
if (ret)
@@ -111,8 +113,6 @@ void run_test()
ok(BSTREAM_EOS == ret,"Moving to next chunk after EOS was hit");
end:
- /* Plan (1..n) must be at the beginning or end of the TAP output. */
- plan(planned);
backup_stream_close(&stream);
}
Attachment: [text/bzr-bundle] bzr/charles.bell@sun.com-20091118173009-vhsciy2p1b9q0wni.bundle
| Thread |
|---|
| • bzr commit into mysql-6.0-backup branch (charles.bell:2889) Bug#47879 | Chuck Bell | 18 Nov |