#At file:///home/kgeorge/mysql/bzr/merge-6.0-main-6.0-bugteam/
2828 Georgi Kodinov 2008-09-10 [merge]
merged 6.0 main to 6.0-bugteam
removed:
mysql-test/r/log_bin_trust_routine_creators_basic.result
mysql-test/t/log_bin_trust_routine_creators_basic.test
added:
mysql-test/r/backup_db_grants.result
mysql-test/r/backup_default.result
mysql-test/r/backup_timeout.result
mysql-test/t/backup_db_grants.test
mysql-test/t/backup_default.test
mysql-test/t/backup_timeout.test
modified:
.bzr-mysql/default.conf
configure.in
mysql-test/lib/mtr_report.pl
mysql-test/r/backup_errors.result
mysql-test/r/backup_views.result
mysql-test/t/backup_errors.test
mysql-test/t/backup_views.test
mysql-test/t/disabled.def
mysql-test/t/union.test
sql/backup/backup_aux.h
sql/backup/backup_info.cc
sql/backup/backup_info.h
sql/backup/backup_test.cc
sql/backup/be_default.cc
sql/backup/image_info.cc
sql/backup/image_info.h
sql/backup/kernel.cc
sql/ddl_blocker.cc
sql/mysql_priv.h
sql/set_var.cc
sql/set_var.h
sql/share/errmsg.txt
sql/si_objects.cc
sql/si_objects.h
sql/sql_class.cc
sql/sql_class.h
sql/sql_parse.cc
=== modified file '.bzr-mysql/default.conf'
--- a/.bzr-mysql/default.conf 2008-09-10 10:40:14 +0000
+++ b/.bzr-mysql/default.conf 2008-09-10 12:50:02 +0000
@@ -1,5 +1,5 @@
-[MYSQL]
-tree_location = bzr+ssh://bk-internal.mysql.com/bzrroot/server/mysql-6.0
-post_commit_to = commits@stripped
-post_push_to = commits@stripped
-tree_name = mysql-6.0
+[MYSQL]
+tree_location = bzr+ssh://bk-internal.mysql.com/bzrroot/server/mysql-6.0
+post_commit_to = commits@stripped.com
+post_push_to = commits@stripped
+tree_name = mysql-6.0
=== modified file 'configure.in'
--- a/configure.in 2008-09-10 10:40:14 +0000
+++ b/configure.in 2008-09-10 12:50:02 +0000
@@ -9,7 +9,7 @@ AC_CANONICAL_SYSTEM
# remember to also update version.c in ndb
# When changing major version number please also check switch statement
# in mysqlbinlog::check_master_version().
-AM_INIT_AUTOMAKE(mysql, 6.0.7-alpha)
+AM_INIT_AUTOMAKE(mysql, 6.0.8-alpha)
AM_CONFIG_HEADER([include/config.h:config.h.in])
NDB_VERSION_MAJOR=6
=== modified file 'mysql-test/lib/mtr_report.pl'
--- a/mysql-test/lib/mtr_report.pl 2008-08-25 14:26:49 +0000
+++ b/mysql-test/lib/mtr_report.pl 2008-09-04 13:46:04 +0000
@@ -346,6 +346,12 @@ sub mtr_report_stats ($) {
/Can't execute this command because another BACKUP\/RESTORE operation is in progress/
) or
+ # backup_db_grants test is supposed to trigger lots of restore warnings
+ ($testname eq 'main.backup_db_grants') and
+ (
+ /Restore:/ or /was skipped because the user does not exist/
+ ) or
+
# The tablespace test triggers error below on purpose
($testname eq 'main.backup_tablespace') and
(
=== added file 'mysql-test/r/backup_db_grants.result'
--- a/mysql-test/r/backup_db_grants.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/backup_db_grants.result 2008-08-25 18:14:40 +0000
@@ -0,0 +1,183 @@
+DROP DATABASE IF EXISTS bup_db_grants;
+DROP DATABASE IF EXISTS db2;
+Create two databases and two tables.
+CREATE DATABASE bup_db_grants;
+CREATE DATABASE db2;
+CREATE TABLE bup_db_grants.t1(a INT);
+CREATE TABLE bup_db_grants.s1(b INT);
+INSERT INTO bup_db_grants.t1 VALUES (1), (2), (3), (4);
+INSERT INTO bup_db_grants.s1 VALUES (10), (20), (30), (40);
+Now create users and assign various rights to the databases
+CREATE USER 'bup_user1'@'%';
+CREATE USER bup_user2;
+CREATE USER 'bup_user3'@'%';
+REVOKE ALL ON *.* FROM 'bup_user1'@'%';
+REVOKE ALL ON *.* FROM bup_user2;
+GRANT ALL ON db2.* TO 'bup_user1'@'%';
+GRANT SELECT ON bup_db_grants.* TO 'bup_user1'@'%';
+GRANT INSERT ON bup_db_grants.* TO bup_user2;
+GRANT ALL ON bup_db_grants.* TO 'no_user'@'%';
+GRANT SELECT (a) ON bup_db_grants.t1 TO 'bup_user1'@'%';
+GRANT SELECT (b), INSERT (b) ON bup_db_grants.s1 TO bup_user2;
+FLUSH PRIVILEGES;
+Demonstrate rights of the users.
+SHOW GRANTS FOR 'bup_user1'@'%';
+Grants for bup_user1@%
+GRANT USAGE ON *.* TO 'bup_user1'@'%'
+GRANT ALL PRIVILEGES ON `db2`.* TO 'bup_user1'@'%'
+GRANT SELECT ON `bup_db_grants`.* TO 'bup_user1'@'%'
+GRANT SELECT (a) ON `bup_db_grants`.`t1` TO 'bup_user1'@'%'
+SHOW GRANTS FOR bup_user2;
+Grants for bup_user2@%
+GRANT USAGE ON *.* TO 'bup_user2'@'%'
+GRANT INSERT ON `bup_db_grants`.* TO 'bup_user2'@'%'
+GRANT SELECT (b), INSERT (b) ON `bup_db_grants`.`s1` TO 'bup_user2'@'%'
+SHOW GRANTS FOR 'bup_user3'@'%';
+Grants for bup_user3@%
+GRANT USAGE ON *.* TO 'bup_user3'@'%'
+SHOW GRANTS FOR 'no_user'@'%';
+Grants for no_user@%
+GRANT USAGE ON *.* TO 'no_user'@'%'
+GRANT ALL PRIVILEGES ON `bup_db_grants`.* TO 'no_user'@'%'
+Run backup
+BACKUP DATABASE bup_db_grants TO 'bup_db_grants.bak';
+backup_id
+#
+Drop users and recreate them (removes grants completely).
+DROP USER 'bup_user1'@'%';
+DROP USER bup_user2;
+DROP USER 'bup_user3'@'%';
+DROP USER 'no_user'@'%';
+FLUSH PRIVILEGES;
+CREATE USER 'bup_user1'@'%';
+CREATE USER bup_user2;
+CREATE USER 'bup_user3'@'%';
+FLUSH PRIVILEGES;
+Demonstrate rights of the users.
+SHOW GRANTS FOR 'bup_user1'@'%';
+Grants for bup_user1@%
+GRANT USAGE ON *.* TO 'bup_user1'@'%'
+SHOW GRANTS FOR bup_user2;
+Grants for bup_user2@%
+GRANT USAGE ON *.* TO 'bup_user2'@'%'
+SHOW GRANTS FOR 'bup_user3'@'%';
+Grants for bup_user3@%
+GRANT USAGE ON *.* TO 'bup_user3'@'%'
+Run Restore
+RESTORE FROM 'bup_db_grants.bak';
+backup_id
+#
+SHOW TABLES FROM bup_db_grants;
+Tables_in_bup_db_grants
+s1
+t1
+Demonstrate rights of the users.
+SHOW GRANTS FOR 'bup_user1'@'%';
+Grants for bup_user1@%
+GRANT USAGE ON *.* TO 'bup_user1'@'%'
+GRANT SELECT ON `bup_db_grants`.* TO 'bup_user1'@'%'
+GRANT SELECT (a) ON `bup_db_grants`.`t1` TO 'bup_user1'@'%'
+SHOW GRANTS FOR bup_user2;
+Grants for bup_user2@%
+GRANT USAGE ON *.* TO 'bup_user2'@'%'
+GRANT INSERT ON `bup_db_grants`.* TO 'bup_user2'@'%'
+GRANT SELECT (b), INSERT (b) ON `bup_db_grants`.`s1` TO 'bup_user2'@'%'
+SHOW GRANTS FOR 'bup_user3'@'%';
+Grants for bup_user3@%
+GRANT USAGE ON *.* TO 'bup_user3'@'%'
+SHOW GRANTS FOR 'no_user'@'%';
+ERROR 42000: There is no such grant defined for user 'no_user' on host '%'
+Now test what happens on backup if users are deleted.
+Drop users and recreate one of them (removes grants completely).
+DROP USER 'bup_user1'@'%';
+DROP USER bup_user2;
+DROP USER 'bup_user3'@'%';
+FLUSH PRIVILEGES;
+CREATE USER 'bup_user1'@'%';
+CREATE USER 'bup_user1'@'nosuchhost';
+Run Restore
+RESTORE FROM 'bup_db_grants.bak';
+backup_id
+#
+SHOW TABLES FROM bup_db_grants;
+Tables_in_bup_db_grants
+s1
+t1
+Demonstrate rights of the users.
+SHOW GRANTS FOR 'bup_user1'@'%';
+Grants for bup_user1@%
+GRANT USAGE ON *.* TO 'bup_user1'@'%'
+GRANT SELECT ON `bup_db_grants`.* TO 'bup_user1'@'%'
+GRANT SELECT (a) ON `bup_db_grants`.`t1` TO 'bup_user1'@'%'
+SHOW GRANTS FOR bup_user2;
+ERROR 42000: There is no such grant defined for user 'bup_user2' on host '%'
+SHOW GRANTS FOR 'bup_user3'@'%';
+ERROR 42000: There is no such grant defined for user 'bup_user3' on host '%'
+SHOW GRANTS FOR 'no_user'@'%';
+ERROR 42000: There is no such grant defined for user 'no_user' on host '%'
+Cleanup
+DROP USER 'bup_user1'@'%';
+DROP USER 'bup_user1'@'nosuchhost';
+DROP USER bup_user2;
+ERROR HY000: Operation DROP USER failed for 'bup_user2'@'%'
+DROP USER 'bup_user3'@'%';
+ERROR HY000: Operation DROP USER failed for 'bup_user3'@'%'
+DROP USER 'no_user'@'%';
+ERROR HY000: Operation DROP USER failed for 'no_user'@'%'
+FLUSH PRIVILEGES;
+Now test for encoded user names with an x40 in the middle.
+SET NAMES sjis;
+DROP DATABASE bup_db_grants;
+Create a database and some tables.
+CREATE DATABASE bup_db_grants;
+CREATE TABLE bup_db_grants.t1(a INT);
+CREATE TABLE bup_db_grants.s1(b INT);
+Create a user with multibyte username with @ in the middle.
+SET @name = CONVERT(0x8340 using sjis);
+SELECT @name;
+@name
+�@
+SET @cmd = CONCAT('CREATE USER ', @name);
+PREPARE stmt1 FROM @cmd;
+EXECUTE stmt1;
+Grant privileges to user.
+SET @cmd = CONCAT('GRANT SELECT ON bup_db_grants.* TO ', @name);
+PREPARE stmt2 from @cmd;
+EXECUTE stmt2;
+FLUSH PRIVILEGES;
+Show existing grants.
+SET @cmd = CONCAT('SHOW GRANTS FOR ', @name);
+PREPARE stmt3 FROM @cmd;
+EXECUTE stmt3;
+Grants for �@@%
+GRANT USAGE ON *.* TO '�@'@'%'
+GRANT SELECT ON `bup_db_grants`.* TO '�@'@'%'
+Backup database.
+BACKUP DATABASE bup_db_grants TO 'bup_db_grants.bak';
+backup_id
+#
+Remove privileges from user.
+SET @cmd = CONCAT('REVOKE ALL ON bup_db_grants.* FROM ', @name);
+PREPARE stmt4 FROM @cmd;
+EXECUTE stmt4;
+FLUSH PRIVILEGES;
+Show existing grants -- should only USAGE.
+EXECUTE stmt3;
+Grants for �@@%
+GRANT USAGE ON *.* TO '�@'@'%'
+Run restore.
+RESTORE FROM 'bup_db_grants.bak';
+backup_id
+#
+FLUSH PRIVILEGES;
+Ensure grants have been restored.
+EXECUTE stmt3;
+Grants for �@@%
+GRANT USAGE ON *.* TO '�@'@'%'
+GRANT SELECT ON `bup_db_grants`.* TO '�@'@'%'
+SET @cmd = CONCAT('DROP USER ', @name);
+PREPARE stmt5 FROM @cmd;
+EXECUTE stmt5;
+SET NAMES latin1;
+DROP DATABASE bup_db_grants;
+DROP DATABASE db2;
=== added file 'mysql-test/r/backup_default.result'
--- a/mysql-test/r/backup_default.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/backup_default.result 2008-08-26 13:28:34 +0000
@@ -0,0 +1,73 @@
+
+Server should not crash for backup using default driver - CSV
+Test for bug#35117
+
+DROP DATABASE IF EXISTS db1;
+CREATE DATABASE db1;
+USE db1;
+CREATE TABLE csv_table(
+id int NOT NULL,
+name char(20) NOT NULL,
+city varchar(20) NOT NULL)
+ENGINE=csv;
+INSERT INTO csv_table VALUES(1,'aa1','bb1'),(2,'aa2','bb2'),(3,'aa3','bb3');
+backup on csv only
+BACKUP DATABASE db1 to 'bup_csv.bak';
+backup_id
+#
+DROP DATABASE db1;
+restore on csv only
+RESTORE FROM 'bup_csv.bak';
+backup_id
+#
+testing content in restored tables
+SELECT * FROM csv_table ORDER BY id;
+id name city
+1 aa1 bb1
+2 aa2 bb2
+3 aa3 bb3
+DROP DATABASE db1;
+
+Server should not crash for backup using default driver
+Partitioned Falcon tables
+Test for bug#33566, bug#36792
+
+CREATE DATABASE db1;
+USE db1;
+CREATE TABLE partition_table (
+int_column int(11),
+char_column char(5))
+engine=falcon
+PARTITION BY HASH (int_column);
+INSERT INTO partition_table VALUES (0,'pVtIa');
+INSERT INTO partition_table VALUES (5,'jTfSg');
+INSERT INTO partition_table VALUES (20,'UezFi');
+INSERT INTO partition_table VALUES (25,'cxmeH');
+INSERT INTO partition_table VALUES (65,'lIuNS');
+testing content in restored tables
+SELECT * FROM partition_table ORDER BY int_column;
+int_column char_column
+0 pVtIa
+5 jTfSg
+20 UezFi
+25 cxmeH
+65 lIuNS
+
+Server should not crash for backup using default driver
+Mix of tables
+
+CREATE TABLE csv_table(
+id int NOT NULL,
+name char(20) NOT NULL,
+city varchar(20) NOT NULL)
+ENGINE=csv;
+INSERT INTO csv_table VALUES(1,'aa1','bb1'),(2,'aa2','bb2'),(3,'aa3','bb3');
+CREATE TABLE myisam_table(
+i int,
+v varchar(20))
+ENGINE=myisam;
+INSERT INTO myisam_table VALUES(1,'v1'),(2,'v2'),(3,'v3');
+
+*** CLEANUP ****
+
+DROP DATABASE db1;
=== modified file 'mysql-test/r/backup_errors.result'
--- a/mysql-test/r/backup_errors.result 2008-03-05 17:48:12 +0000
+++ b/mysql-test/r/backup_errors.result 2008-08-21 11:36:09 +0000
@@ -95,3 +95,41 @@ Restoring the table
CREATE TABLE mysql.online_backup_progress LIKE test.obp_copy;
DROP TABLE test.obp_copy;
DROP DATABASE test_ob_error;
+
+Bug#38624
+Test that backup fails with error if database files are removed
+after backup starts
+SET DEBUG_SYNC= 'reset';
+DROP DATABASE IF EXISTS db1;
+CREATE DATABASE db1;
+start backup but stop just before adding metadata to backup image
+SET DEBUG_SYNC= 'backup_before_write_preamble SIGNAL running WAIT_FOR db_will_fail';
+BACKUP DATABASE db1 TO 'bup_db1.bak';
+SET DEBUG_SYNC='now WAIT_FOR running';
+delete database files so that check_db_dir_exists will fail in
+si_objects.cc @ DatabaseObj::do_serialize
+SET DEBUG_SYNC='now SIGNAL db_will_fail';
+Database has been deleted, backup will fail
+ERROR 42000: Unknown database 'db1'
+
+Test that backup fails with error if a table used by
+a trigger cannot be opened
+SET DEBUG_SYNC= 'reset';
+DROP DATABASE IF EXISTS db1;
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (i int);
+CREATE TABLE db1.t2 (v varchar (20));
+CREATE TRIGGER db1.trg AFTER INSERT ON db1.t1 FOR EACH ROW
+BEGIN
+INSERT INTO db1.t2(v) VALUES ('Test trigger fired');
+END;||
+SET DEBUG_SYNC= 'reset';
+Setting debug point that will make backup fail when adding the
+trigger metadata
+SET SESSION DEBUG='+d,backup_fail_add_trigger';
+BACKUP DATABASE db1 TO 'bup_db1.bak';
+ERROR HY000: Failed to obtain meta-data for trigger `db1`.`trg`
+SET DEBUG_SYNC= 'reset';
+DROP DATABASE db1;
+
+Done testing for Bug#38624
=== added file 'mysql-test/r/backup_timeout.result'
--- a/mysql-test/r/backup_timeout.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/backup_timeout.result 2008-08-19 15:35:29 +0000
@@ -0,0 +1,73 @@
+SET DEBUG_SYNC= 'reset';
+DROP DATABASE IF EXISTS bup_ddl_blocker;
+CREATE DATABASE bup_ddl_blocker;
+con1: Creating tables
+CREATE TABLE bup_ddl_blocker.t1 (col_a CHAR(40)) ENGINE=INNODB;
+con1: Loading data
+INSERT INTO bup_ddl_blocker.t1 VALUES ("01 Some data to test");
+INSERT INTO bup_ddl_blocker.t1 VALUES ("02 Some data to test");
+INSERT INTO bup_ddl_blocker.t1 VALUES ("03 Some data to test");
+SHOW VARIABLES LIKE 'backup_wait%';
+Variable_name Value
+backup_wait_timeout 50
+Part A
+con1: Activate synchronization points for backup.
+SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_blocked WAIT_FOR timeout_done';
+con1: Get a backup going and stop after the DDL blocker is fired.
+BACKUP DATABASE bup_ddl_blocker TO "bup_ddl_blocker.bak";
+SET DEBUG_SYNC= 'now WAIT_FOR bup_blocked';
+Set ddl timeout to 1 second
+SET backup_wait_timeout = 1;
+SHOW VARIABLES LIKE 'backup_wait%';
+Variable_name Value
+backup_wait_timeout 1
+con2: Try a ddl operation and watch it expire
+CREATE TABLE bup_ddl_blocker.t2 (col_a CHAR(40)) ENGINE=MEMORY;
+ERROR HY000: The backup wait timeout has expired for query 'CREATE TABLE bup_ddl_blocker.t2 (col_a CHAR(40)) ENGINE=MEMORY'.
+release the lock.
+con5: Resume all.
+SET DEBUG_SYNC= 'now SIGNAL timeout_done';
+backup_id
+#
+Part B
+con1: Activate synchronization points for backup.
+SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_blocked WAIT_FOR timeout_done';
+con1: Get a backup going and stop after the DDL blocker is fired.
+BACKUP DATABASE bup_ddl_blocker TO "bup_ddl_blocker.bak";
+SET DEBUG_SYNC= 'now WAIT_FOR bup_blocked';
+Set ddl timeout to 0 seconds
+SET backup_wait_timeout = 0;
+SHOW VARIABLES LIKE 'backup_wait%';
+Variable_name Value
+backup_wait_timeout 0
+con2: Try a ddl operation and it should expire
+CREATE TABLE bup_ddl_blocker.t3 (col_a CHAR(40)) ENGINE=MEMORY;
+ERROR HY000: The backup wait timeout has expired for query 'CREATE TABLE bup_ddl_blocker.t3 (col_a CHAR(40)) ENGINE=MEMORY'.
+SET backup_wait_timeout = 100;
+SHOW VARIABLES LIKE 'backup_wait%';
+Variable_name Value
+backup_wait_timeout 100
+con3: Try a ddl operation and it should not expire
+CREATE TABLE bup_ddl_blocker.t3 (col_a CHAR(40)) ENGINE=MEMORY;
+release the lock.
+con5: Resume all.
+SET DEBUG_SYNC= 'now SIGNAL timeout_done';
+backup_id
+#
+USE bup_ddl_blocker;
+SHOW FULL TABLES;
+Tables_in_bup_ddl_blocker Table_type
+t1 BASE TABLE
+t3 BASE TABLE
+Part C
+Show that the variable can be reset to its timeout value using
+SET backup_wait_timeout = DEFAULT;
+SET backup_wait_timeout = 1;
+SHOW VARIABLES LIKE 'backup_wait%';
+Variable_name Value
+backup_wait_timeout 1
+SET backup_wait_timeout = DEFAULT;
+SHOW VARIABLES LIKE 'backup_wait%';
+Variable_name Value
+backup_wait_timeout 50
+DROP DATABASE bup_ddl_blocker;
=== modified file 'mysql-test/r/backup_views.result'
--- a/mysql-test/r/backup_views.result 2008-08-11 10:41:41 +0000
+++ b/mysql-test/r/backup_views.result 2008-08-20 13:23:10 +0000
@@ -277,10 +277,10 @@ DROP DATABASE bup_db2;
Restore database.
restore database with view dependency to other, non-existing db
RESTORE FROM 'bup_objectview1.bak';
-ERROR 42S02: Table 'bup_db2.t2' doesn't exist
+ERROR HY000: Could not restore view `bup_db1`.`v5`. Please check the view definition for possible missing dependencies.
DROP DATABASE bup_db1;
RESTORE FROM 'bup_objectview2.bak';
-ERROR 42S02: Table 'bup_db1.t3' doesn't exist
+ERROR HY000: Could not restore view `bup_db2`.`student_details`. Please check the view definition for possible missing dependencies.
DROP DATABASE bup_db2;
RESTORE FROM 'bup_objectview.bak';
backup_id
=== removed file 'mysql-test/r/log_bin_trust_routine_creators_basic.result'
--- a/mysql-test/r/log_bin_trust_routine_creators_basic.result 2008-04-10 13:14:28 +0000
+++ b/mysql-test/r/log_bin_trust_routine_creators_basic.result 1970-01-01 00:00:00 +0000
@@ -1,121 +0,0 @@
-SET @start_global_value = @@global.log_bin_trust_routine_creators;
-SELECT @start_global_value;
-@start_global_value
-1
-'#--------------------FN_DYNVARS_064_01-------------------------#'
-SET @@global.log_bin_trust_routine_creators = TRUE;
-Warnings:
-Warning 1287 The syntax 'log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.2. Please use 'log_bin_trust_function_creators' instead
-SET @@global.log_bin_trust_routine_creators = DEFAULT;
-Warnings:
-Warning 1287 The syntax 'log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.2. Please use 'log_bin_trust_function_creators' instead
-SELECT @@global.log_bin_trust_routine_creators;
-@@global.log_bin_trust_routine_creators
-0
-'#--------------------FN_DYNVARS_064_02-------------------------#'
-SET @@global.log_bin_trust_routine_creators = DEFAULT;
-Warnings:
-Warning 1287 The syntax 'log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.2. Please use 'log_bin_trust_function_creators' instead
-SELECT @@global.log_bin_trust_routine_creators = 'FALSE';
-@@global.log_bin_trust_routine_creators = 'FALSE'
-1
-Warnings:
-Warning 1292 Truncated incorrect DOUBLE value: 'FALSE'
-'#--------------------FN_DYNVARS_064_03-------------------------#'
-SET @@global.log_bin_trust_routine_creators = ON;
-Warnings:
-Warning 1287 The syntax 'log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.2. Please use 'log_bin_trust_function_creators' instead
-SELECT @@global.log_bin_trust_routine_creators;
-@@global.log_bin_trust_routine_creators
-1
-SET @@global.log_bin_trust_routine_creators = OFF;
-Warnings:
-Warning 1287 The syntax 'log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.2. Please use 'log_bin_trust_function_creators' instead
-SELECT @@global.log_bin_trust_routine_creators;
-@@global.log_bin_trust_routine_creators
-0
-SET @@global.log_bin_trust_routine_creators = 0;
-Warnings:
-Warning 1287 The syntax 'log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.2. Please use 'log_bin_trust_function_creators' instead
-SELECT @@global.log_bin_trust_routine_creators;
-@@global.log_bin_trust_routine_creators
-0
-SET @@global.log_bin_trust_routine_creators = 1;
-Warnings:
-Warning 1287 The syntax 'log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.2. Please use 'log_bin_trust_function_creators' instead
-SELECT @@global.log_bin_trust_routine_creators;
-@@global.log_bin_trust_routine_creators
-1
-SET @@global.log_bin_trust_routine_creators = TRUE;
-Warnings:
-Warning 1287 The syntax 'log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.2. Please use 'log_bin_trust_function_creators' instead
-SELECT @@global.log_bin_trust_routine_creators;
-@@global.log_bin_trust_routine_creators
-1
-SET @@global.log_bin_trust_routine_creators = FALSE;
-Warnings:
-Warning 1287 The syntax 'log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.2. Please use 'log_bin_trust_function_creators' instead
-SELECT @@global.log_bin_trust_routine_creators;
-@@global.log_bin_trust_routine_creators
-0
-'#-------------------FN_DYNVARS_064_04----------------------------#'
-SET @@session.log_bin_trust_routine_creators = 0;
-ERROR HY000: Variable 'log_bin_trust_routine_creators' is a GLOBAL variable and should be set with SET GLOBAL
-SELECT @@session.log_bin_trust_routine_creators;
-ERROR HY000: Variable 'log_bin_trust_routine_creators' is a GLOBAL variable
-'#------------------FN_DYNVARS_064_05-----------------------#'
-SET @@global.log_bin_trust_routine_creators = 'ONN';
-ERROR 42000: Variable 'log_bin_trust_routine_creators' can't be set to the value of 'ONN'
-SET @@global.log_bin_trust_routine_creators = "OFFF";
-ERROR 42000: Variable 'log_bin_trust_routine_creators' can't be set to the value of 'OFFF'
-SET @@global.log_bin_trust_routine_creators = OF;
-Warnings:
-Warning 1287 The syntax 'log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.2. Please use 'log_bin_trust_function_creators' instead
-SELECT @@global.log_bin_trust_routine_creators;
-@@global.log_bin_trust_routine_creators
-0
-'Bug# 34828: OF is also working as OFF and no error is coming';
-SET @@global.log_bin_trust_routine_creators = TTRUE;
-ERROR 42000: Variable 'log_bin_trust_routine_creators' can't be set to the value of 'TTRUE'
-SET @@global.log_bin_trust_routine_creators = FELSE;
-ERROR 42000: Variable 'log_bin_trust_routine_creators' can't be set to the value of 'FELSE'
-SET @@global.log_bin_trust_routine_creators = -1024;
-ERROR 42000: Variable 'log_bin_trust_routine_creators' can't be set to the value of '-1024'
-SET @@global.log_bin_trust_routine_creators = 65536;
-ERROR 42000: Variable 'log_bin_trust_routine_creators' can't be set to the value of '65536'
-SET @@global.log_bin_trust_routine_creators = 65530.34;
-ERROR 42000: Variable 'log_bin_trust_routine_creators' can't be set to the value of '65530'
-SET @@global.log_bin_trust_routine_creators = test;
-ERROR 42000: Variable 'log_bin_trust_routine_creators' can't be set to the value of 'test'
-'#------------------FN_DYNVARS_064_06-----------------------#'
-SELECT @@global.log_bin_trust_routine_creators = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_bin_trust_routine_creators';
-@@global.log_bin_trust_routine_creators = VARIABLE_VALUE
-1
-SELECT @@session.log_bin_trust_routine_creators = VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='log_bin_trust_routine_creators';
-ERROR HY000: Variable 'log_bin_trust_routine_creators' is a GLOBAL variable
-'#---------------------FN_DYNVARS_064_07----------------------#'
-SET @@global.log_bin_trust_routine_creators = TRUE;
-Warnings:
-Warning 1287 The syntax 'log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.2. Please use 'log_bin_trust_function_creators' instead
-SELECT @@log_bin_trust_routine_creators = @@global.log_bin_trust_routine_creators;
-@@log_bin_trust_routine_creators = @@global.log_bin_trust_routine_creators
-1
-'#---------------------FN_DYNVARS_064_08----------------------#'
-SET @@global.log_bin_trust_routine_creators = TRUE;
-Warnings:
-Warning 1287 The syntax 'log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.2. Please use 'log_bin_trust_function_creators' instead
-SELECT @@log_bin_trust_routine_creators;
-@@log_bin_trust_routine_creators
-1
-SELECT local.log_bin_trust_routine_creators;
-ERROR 42S02: Unknown table 'local' in field list
-SELECT session.log_bin_trust_routine_creators;
-ERROR 42S02: Unknown table 'session' in field list
-SELECT log_bin_trust_routine_creators = @@session.log_bin_trust_routine_creators;
-ERROR 42S22: Unknown column 'log_bin_trust_routine_creators' in 'field list'
-SET @@global.log_bin_trust_routine_creators = @start_global_value;
-Warnings:
-Warning 1287 The syntax 'log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.2. Please use 'log_bin_trust_function_creators' instead
-SELECT @@global.log_bin_trust_routine_creators;
-@@global.log_bin_trust_routine_creators
-1
=== added file 'mysql-test/t/backup_db_grants.test'
--- a/mysql-test/t/backup_db_grants.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/backup_db_grants.test 2008-08-25 18:14:40 +0000
@@ -0,0 +1,198 @@
+#
+# Test the backup of database grants
+#
+
+--source include/not_embedded.inc
+--source include/have_sjis.inc
+
+--disable_warnings
+DROP DATABASE IF EXISTS bup_db_grants;
+DROP DATABASE IF EXISTS db2;
+--enable_warnings
+
+--echo Create two databases and two tables.
+CREATE DATABASE bup_db_grants;
+CREATE DATABASE db2;
+CREATE TABLE bup_db_grants.t1(a INT);
+CREATE TABLE bup_db_grants.s1(b INT);
+INSERT INTO bup_db_grants.t1 VALUES (1), (2), (3), (4);
+INSERT INTO bup_db_grants.s1 VALUES (10), (20), (30), (40);
+
+--echo Now create users and assign various rights to the databases
+CREATE USER 'bup_user1'@'%';
+CREATE USER bup_user2;
+CREATE USER 'bup_user3'@'%';
+REVOKE ALL ON *.* FROM 'bup_user1'@'%';
+REVOKE ALL ON *.* FROM bup_user2;
+GRANT ALL ON db2.* TO 'bup_user1'@'%';
+GRANT SELECT ON bup_db_grants.* TO 'bup_user1'@'%';
+GRANT INSERT ON bup_db_grants.* TO bup_user2;
+GRANT ALL ON bup_db_grants.* TO 'no_user'@'%';
+GRANT SELECT (a) ON bup_db_grants.t1 TO 'bup_user1'@'%';
+GRANT SELECT (b), INSERT (b) ON bup_db_grants.s1 TO bup_user2;
+FLUSH PRIVILEGES;
+
+--echo Demonstrate rights of the users.
+SHOW GRANTS FOR 'bup_user1'@'%';
+SHOW GRANTS FOR bup_user2;
+SHOW GRANTS FOR 'bup_user3'@'%';
+SHOW GRANTS FOR 'no_user'@'%';
+
+--echo Run backup
+--replace_column 1 #
+BACKUP DATABASE bup_db_grants TO 'bup_db_grants.bak';
+
+--echo Drop users and recreate them (removes grants completely).
+DROP USER 'bup_user1'@'%';
+DROP USER bup_user2;
+DROP USER 'bup_user3'@'%';
+DROP USER 'no_user'@'%';
+
+FLUSH PRIVILEGES;
+
+CREATE USER 'bup_user1'@'%';
+CREATE USER bup_user2;
+CREATE USER 'bup_user3'@'%';
+
+FLUSH PRIVILEGES;
+
+--echo Demonstrate rights of the users.
+SHOW GRANTS FOR 'bup_user1'@'%';
+SHOW GRANTS FOR bup_user2;
+SHOW GRANTS FOR 'bup_user3'@'%';
+
+--echo Run Restore
+--replace_column 1 #
+RESTORE FROM 'bup_db_grants.bak';
+
+SHOW TABLES FROM bup_db_grants;
+
+--echo Demonstrate rights of the users.
+# Note: Since db2 was not in the backup and the user was deleted prior to
+# the restore, that privilege will not appear here.
+SHOW GRANTS FOR 'bup_user1'@'%';
+SHOW GRANTS FOR bup_user2;
+SHOW GRANTS FOR 'bup_user3'@'%';
+--error ER_NONEXISTING_GRANT
+SHOW GRANTS FOR 'no_user'@'%';
+
+--echo Now test what happens on backup if users are deleted.
+
+--echo Drop users and recreate one of them (removes grants completely).
+DROP USER 'bup_user1'@'%';
+DROP USER bup_user2;
+DROP USER 'bup_user3'@'%';
+
+FLUSH PRIVILEGES;
+
+CREATE USER 'bup_user1'@'%';
+CREATE USER 'bup_user1'@'nosuchhost';
+
+--echo Run Restore
+--replace_column 1 #
+RESTORE FROM 'bup_db_grants.bak';
+
+SHOW TABLES FROM bup_db_grants;
+
+--echo Demonstrate rights of the users.
+SHOW GRANTS FOR 'bup_user1'@'%';
+--error ER_NONEXISTING_GRANT
+SHOW GRANTS FOR bup_user2;
+--error ER_NONEXISTING_GRANT
+SHOW GRANTS FOR 'bup_user3'@'%';
+--error ER_NONEXISTING_GRANT
+SHOW GRANTS FOR 'no_user'@'%';
+
+#
+# Section of test disabled due to errors in PB. See BUG#39016
+#
+#--echo Now demonstrate what happens when grants are altered in backup image.
+#
+#--exec perl -pi.bak -e "s/ON bup/ON boo/" $MYSQLTEST_VARDIR/master-data/bup_db_grants.bak
+#--echo Run Restore
+#--error ER_BACKUP_GRANT_WRONG_DB
+#RESTORE FROM 'bup_db_grants.bak';
+#
+#FLUSH PRIVILEGES;
+
+--echo Cleanup
+
+DROP USER 'bup_user1'@'%';
+DROP USER 'bup_user1'@'nosuchhost';
+--error ER_CANNOT_USER
+DROP USER bup_user2;
+--error ER_CANNOT_USER
+DROP USER 'bup_user3'@'%';
+--error ER_CANNOT_USER
+DROP USER 'no_user'@'%';
+
+FLUSH PRIVILEGES;
+
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_db_grants.bak
+
+#--remove_file $MYSQLTEST_VARDIR/master-data/bup_db_grants.bak.bak
+
+--echo Now test for encoded user names with an x40 in the middle.
+
+SET NAMES sjis;
+
+DROP DATABASE bup_db_grants;
+
+--echo Create a database and some tables.
+CREATE DATABASE bup_db_grants;
+CREATE TABLE bup_db_grants.t1(a INT);
+CREATE TABLE bup_db_grants.s1(b INT);
+
+--echo Create a user with multibyte username with @ in the middle.
+SET @name = CONVERT(0x8340 using sjis);
+SELECT @name;
+SET @cmd = CONCAT('CREATE USER ', @name);
+PREPARE stmt1 FROM @cmd;
+EXECUTE stmt1;
+
+--echo Grant privileges to user.
+SET @cmd = CONCAT('GRANT SELECT ON bup_db_grants.* TO ', @name);
+PREPARE stmt2 from @cmd;
+EXECUTE stmt2;
+
+FLUSH PRIVILEGES;
+
+--echo Show existing grants.
+SET @cmd = CONCAT('SHOW GRANTS FOR ', @name);
+PREPARE stmt3 FROM @cmd;
+EXECUTE stmt3;
+
+--echo Backup database.
+--replace_column 1 #
+BACKUP DATABASE bup_db_grants TO 'bup_db_grants.bak';
+
+--echo Remove privileges from user.
+SET @cmd = CONCAT('REVOKE ALL ON bup_db_grants.* FROM ', @name);
+PREPARE stmt4 FROM @cmd;
+EXECUTE stmt4;
+
+FLUSH PRIVILEGES;
+
+--echo Show existing grants -- should only USAGE.
+EXECUTE stmt3;
+
+--echo Run restore.
+--replace_column 1 #
+RESTORE FROM 'bup_db_grants.bak';
+
+FLUSH PRIVILEGES;
+
+--echo Ensure grants have been restored.
+EXECUTE stmt3;
+
+SET @cmd = CONCAT('DROP USER ', @name);
+PREPARE stmt5 FROM @cmd;
+EXECUTE stmt5;
+
+SET NAMES latin1;
+
+DROP DATABASE bup_db_grants;
+DROP DATABASE db2;
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_db_grants.bak
=== added file 'mysql-test/t/backup_default.test'
--- a/mysql-test/t/backup_default.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/backup_default.test 2008-08-26 13:28:34 +0000
@@ -0,0 +1,136 @@
+###########################################################################
+# Purpose: To test backup using default driver
+###############################################################################
+--source include/have_falcon.inc
+--source include/have_partition.inc
+--source include/not_embedded.inc
+
+--echo
+--echo Server should not crash for backup using default driver - CSV
+--echo Test for bug#35117
+--echo
+
+--disable_warnings
+DROP DATABASE IF EXISTS db1;
+--enable_warnings
+
+CREATE DATABASE db1;
+USE db1;
+
+# csv uses default driver
+CREATE TABLE csv_table(
+ id int NOT NULL,
+ name char(20) NOT NULL,
+ city varchar(20) NOT NULL)
+ENGINE=csv;
+
+INSERT INTO csv_table VALUES(1,'aa1','bb1'),(2,'aa2','bb2'),(3,'aa3','bb3');
+
+--echo backup on csv only
+--replace_column 1 #
+BACKUP DATABASE db1 to 'bup_csv.bak';
+
+DROP DATABASE db1;
+
+--echo restore on csv only
+--replace_column 1 #
+RESTORE FROM 'bup_csv.bak';
+
+--echo testing content in restored tables
+SELECT * FROM csv_table ORDER BY id;
+
+DROP DATABASE db1;
+
+--echo
+--echo Server should not crash for backup using default driver
+--echo Partitioned Falcon tables
+--echo Test for bug#33566, bug#36792
+--echo
+
+CREATE DATABASE db1;
+USE db1;
+
+CREATE TABLE partition_table (
+ int_column int(11),
+ char_column char(5))
+engine=falcon
+PARTITION BY HASH (int_column);
+
+INSERT INTO partition_table VALUES (0,'pVtIa');
+INSERT INTO partition_table VALUES (5,'jTfSg');
+INSERT INTO partition_table VALUES (20,'UezFi');
+INSERT INTO partition_table VALUES (25,'cxmeH');
+INSERT INTO partition_table VALUES (65,'lIuNS');
+
+#
+# This portion of the test has been disabled. See BUG#39017
+#
+#--echo backup on partitioned falcon
+#--replace_column 1 #
+#BACKUP DATABASE db1 to 'bup_falcon.bak';
+#
+#DROP DATABASE db1;
+#
+#--echo restore on partitioned falcon
+#--replace_column 1 #
+#RESTORE FROM 'bup_falcon.bak';
+
+--echo testing content in restored tables
+SELECT * FROM partition_table ORDER BY int_column;
+
+
+--echo
+--echo Server should not crash for backup using default driver
+--echo Mix of tables
+--echo
+
+# partition_table already exists in the database
+# re-create the csv_table
+CREATE TABLE csv_table(
+ id int NOT NULL,
+ name char(20) NOT NULL,
+ city varchar(20) NOT NULL)
+ENGINE=csv;
+
+INSERT INTO csv_table VALUES(1,'aa1','bb1'),(2,'aa2','bb2'),(3,'aa3','bb3');
+
+# create a myisam table (not default driver)
+CREATE TABLE myisam_table(
+ i int,
+ v varchar(20))
+ENGINE=myisam;
+
+INSERT INTO myisam_table VALUES(1,'v1'),(2,'v2'),(3,'v3');
+
+#
+# This portion of the test has been disabled. See BUG#39017
+#
+#--echo backup on mixed table database
+#--replace_column 1 #
+#BACKUP DATABASE db1 to 'bup_mixed.bak';
+#
+#DROP DATABASE db1;
+#
+#--echo restore on mixed table database
+#--replace_column 1 #
+#RESTORE FROM 'bup_mixed.bak';
+#
+#--echo testing content in restored tables
+#SELECT * FROM partition_table ORDER BY int_column;
+#SELECT * FROM csv_table ORDER BY id;
+#SELECT * FROM myisam_table ORDER BY i;
+
+
+# Test cleanup section
+
+--echo
+--echo *** CLEANUP ****
+--echo
+
+
+DROP DATABASE db1;
+
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_csv.bak
+#--remove_file $MYSQLTEST_VARDIR/master-data/bup_falcon.bak
+#--remove_file $MYSQLTEST_VARDIR/master-data/bup_mixed.bak
+
=== modified file 'mysql-test/t/backup_errors.test'
--- a/mysql-test/t/backup_errors.test 2008-03-04 17:09:56 +0000
+++ b/mysql-test/t/backup_errors.test 2008-08-21 11:36:09 +0000
@@ -1,4 +1,6 @@
--source include/not_embedded.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
# Check that BACKUP/RESTORE commands correctly report errors
#
@@ -209,3 +211,82 @@ CREATE TABLE mysql.online_backup_progres
DROP TABLE test.obp_copy;
DROP DATABASE test_ob_error;
+
+
+--echo
+--echo Bug#38624
+--echo Test that backup fails with error if database files are removed
+--echo after backup starts
+
+SET DEBUG_SYNC= 'reset';
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+
+connection con1;
+
+--disable_warnings
+DROP DATABASE IF EXISTS db1;
+
+CREATE DATABASE db1;
+
+connection con2;
+
+--echo start backup but stop just before adding metadata to backup image
+SET DEBUG_SYNC= 'backup_before_write_preamble SIGNAL running WAIT_FOR db_will_fail';
+
+send BACKUP DATABASE db1 TO 'bup_db1.bak';
+
+connection con1;
+
+SET DEBUG_SYNC='now WAIT_FOR running';
+
+--echo delete database files so that check_db_dir_exists will fail in
+--echo si_objects.cc @ DatabaseObj::do_serialize
+
+--remove_file $MYSQLTEST_VARDIR/master-data/db1/db.opt
+--rmdir $MYSQLTEST_VARDIR/master-data/db1
+
+SET DEBUG_SYNC='now SIGNAL db_will_fail';
+
+connection con2;
+--echo Database has been deleted, backup will fail
+--error ER_BAD_DB_ERROR
+reap;
+
+--echo
+--echo Test that backup fails with error if a table used by
+--echo a trigger cannot be opened
+
+SET DEBUG_SYNC= 'reset';
+
+connection con1;
+
+--disable_warnings
+DROP DATABASE IF EXISTS db1;
+
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (i int);
+CREATE TABLE db1.t2 (v varchar (20));
+
+DELIMITER ||;
+CREATE TRIGGER db1.trg AFTER INSERT ON db1.t1 FOR EACH ROW
+BEGIN
+ INSERT INTO db1.t2(v) VALUES ('Test trigger fired');
+END;||
+DELIMITER ;||
+
+SET DEBUG_SYNC= 'reset';
+
+--echo Setting debug point that will make backup fail when adding the
+--echo trigger metadata
+
+SET SESSION DEBUG='+d,backup_fail_add_trigger';
+--error ER_BACKUP_GET_META_TRIGGER
+BACKUP DATABASE db1 TO 'bup_db1.bak';
+
+SET DEBUG_SYNC= 'reset';
+DROP DATABASE db1;
+
+--echo
+--echo Done testing for Bug#38624
=== added file 'mysql-test/t/backup_timeout.test'
--- a/mysql-test/t/backup_timeout.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/backup_timeout.test 2008-08-19 15:35:29 +0000
@@ -0,0 +1,162 @@
+#
+# This test is for the DDL blocker timeout feature.
+#
+
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/not_embedded.inc
+--source include/have_debug_sync.inc
+
+SET DEBUG_SYNC= 'reset';
+
+#
+# Remove backup files (if they exist)
+#
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker.bak;
+
+#
+# Connections used in this test
+#
+# con1 used to create data, load data, and run the backup
+# con2-con4 used for DDL statements: 2 before backup and 2 during backup
+# con5 used for setting and releasing breakpoints
+#
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+connect (con3,localhost,root,,);
+connect (con4,localhost,root,,);
+connect (con5,localhost,root,,);
+
+connection con1;
+
+# Create data for this test and tailor it to the test.
+--disable_warnings
+DROP DATABASE IF EXISTS bup_ddl_blocker;
+--enable_warnings
+
+CREATE DATABASE bup_ddl_blocker;
+
+# Create a table and load it with data.
+--echo con1: Creating tables
+CREATE TABLE bup_ddl_blocker.t1 (col_a CHAR(40)) ENGINE=INNODB;
+
+--echo con1: Loading data
+INSERT INTO bup_ddl_blocker.t1 VALUES ("01 Some data to test");
+INSERT INTO bup_ddl_blocker.t1 VALUES ("02 Some data to test");
+INSERT INTO bup_ddl_blocker.t1 VALUES ("03 Some data to test");
+
+SHOW VARIABLES LIKE 'backup_wait%';
+
+#
+# Part A - test timeout for one session
+#
+--echo Part A
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker.bak
+
+connection con1;
+
+--echo con1: Activate synchronization points for backup.
+SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_blocked WAIT_FOR timeout_done';
+
+--echo con1: Get a backup going and stop after the DDL blocker is fired.
+send BACKUP DATABASE bup_ddl_blocker TO "bup_ddl_blocker.bak";
+
+connection con2;
+
+SET DEBUG_SYNC= 'now WAIT_FOR bup_blocked';
+
+--echo Set ddl timeout to 1 second
+SET backup_wait_timeout = 1;
+SHOW VARIABLES LIKE 'backup_wait%';
+
+--echo con2: Try a ddl operation and watch it expire
+--error ER_DDL_TIMEOUT
+CREATE TABLE bup_ddl_blocker.t2 (col_a CHAR(40)) ENGINE=MEMORY;
+
+connection con5;
+--echo release the lock.
+--echo con5: Resume all.
+SET DEBUG_SYNC= 'now SIGNAL timeout_done';
+
+# Reconnect to con1 and let backup finish.
+
+connection con1;
+--replace_column 1 #
+reap;
+
+#
+# Part B - test timeout for a session with a timeout,
+# and a session with no timeout (backup_wait_timeout = 0)
+#
+--echo Part B
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker.bak
+
+connection con1;
+
+--echo con1: Activate synchronization points for backup.
+SET DEBUG_SYNC= 'after_block_ddl SIGNAL bup_blocked WAIT_FOR timeout_done';
+
+--echo con1: Get a backup going and stop after the DDL blocker is fired.
+send BACKUP DATABASE bup_ddl_blocker TO "bup_ddl_blocker.bak";
+
+connection con2;
+
+SET DEBUG_SYNC= 'now WAIT_FOR bup_blocked';
+
+--echo Set ddl timeout to 0 seconds
+SET backup_wait_timeout = 0;
+SHOW VARIABLES LIKE 'backup_wait%';
+
+--echo con2: Try a ddl operation and it should expire
+--error ER_DDL_TIMEOUT
+CREATE TABLE bup_ddl_blocker.t3 (col_a CHAR(40)) ENGINE=MEMORY;
+
+connection con3;
+
+SET backup_wait_timeout = 100;
+SHOW VARIABLES LIKE 'backup_wait%';
+
+--echo con3: Try a ddl operation and it should not expire
+send CREATE TABLE bup_ddl_blocker.t3 (col_a CHAR(40)) ENGINE=MEMORY;
+
+connection con5;
+--echo release the lock.
+--echo con5: Resume all.
+SET DEBUG_SYNC= 'now SIGNAL timeout_done';
+
+# Reconnect to con1 and let backup finish.
+
+connection con1;
+--replace_column 1 #
+reap;
+
+connection con3;
+reap;
+
+USE bup_ddl_blocker;
+SHOW FULL TABLES;
+
+#
+# Part C - test default behavior: set backup timeout = default
+#
+--echo Part C
+
+connection con1;
+
+--echo Show that the variable can be reset to its timeout value using
+--echo SET backup_wait_timeout = DEFAULT;
+SET backup_wait_timeout = 1;
+SHOW VARIABLES LIKE 'backup_wait%';
+SET backup_wait_timeout = DEFAULT;
+SHOW VARIABLES LIKE 'backup_wait%';
+
+DROP DATABASE bup_ddl_blocker;
+
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_ddl_blocker.bak
=== modified file 'mysql-test/t/backup_views.test'
--- a/mysql-test/t/backup_views.test 2008-08-11 10:41:41 +0000
+++ b/mysql-test/t/backup_views.test 2008-08-20 13:23:10 +0000
@@ -205,14 +205,14 @@ DROP DATABASE bup_db2;
--echo restore database with view dependency to other, non-existing db
---error ER_NO_SUCH_TABLE
+--error ER_BACKUP_CANT_RESTORE_VIEW
RESTORE FROM 'bup_objectview1.bak';
# An incomplete bup_db1 was created by the failing restore operation.
# Remove it before trying restore of bup_db2.
DROP DATABASE bup_db1;
---error ER_NO_SUCH_TABLE
+--error ER_BACKUP_CANT_RESTORE_VIEW
RESTORE FROM 'bup_objectview2.bak';
# An incomplete bup_db2 was created by the failing restore operation.
=== modified file 'mysql-test/t/disabled.def'
--- a/mysql-test/t/disabled.def 2008-09-01 09:28:27 +0000
+++ b/mysql-test/t/disabled.def 2008-09-04 13:46:04 +0000
@@ -17,7 +17,6 @@ lowercase_table3 : Bug#32667 low
rpl_log_pos : Bug#8693 Test 'rpl_log_pos' fails sometimes
ctype_create : Bug#32965 main.ctype_create fails
backup_no_engine : Bug#36021 2008-04-13 rsomla server crashes when openning table with unknown storage engine
-backup_tablespace : Bug #36973 backup_tablespace.test fails in pushbuild
csv_alter_table : Bug#33696 2008-01-21 pcrews no .result file - bug allows NULL columns in CSV tables
query_cache_wlock_invalidate_func: Bug#35390 causes not deterministic results.
thread_cache_size_func: BUG#35988, BUG#36733 Due to not deterministic results
@@ -39,6 +38,5 @@ key_buffer_size_basic_32 : Bug#36876
max_heap_table_size_basic_32 : Bug#36877 main.max_heap_table_size_basic_32 fails on some systems
tmp_table_size_basic_32 : Bug#36878 main.tmp_table_size_basic_32 fails on some systems
backup_triggers_and_events : Bug#37762 2008-07-01 rafal Test fails on remove_file for unknown reasons
-backup_tablespace : Bug#36973 2008-07-01 rafal
backup_no_be : Bug#38023 2008-07-16 rafal Test triggers valgrind warnings described in the bug
user_limits : Bug#23921 2008-07-25 joro random failure of user_limits.test
=== removed file 'mysql-test/t/log_bin_trust_routine_creators_basic.test'
--- a/mysql-test/t/log_bin_trust_routine_creators_basic.test 2008-04-10 13:14:28 +0000
+++ b/mysql-test/t/log_bin_trust_routine_creators_basic.test 1970-01-01 00:00:00 +0000
@@ -1,164 +0,0 @@
-############## mysql-test\t\log_bin_trust_routine_creators_basic.test #########
-# #
-# Variable Name: log_bin_trust_routine_creators #
-# Scope: GLOBAL #
-# Access Type: Dynamic #
-# Data Type: boolean #
-# Default Value: False #
-# Range: #
-# #
-# #
-# Creation Date: 2008-02-12 #
-# Author: Salman #
-# #
-# Description: Test Cases of Dynamic System Variable #
-# log_bin_trust_routine_creators that checks the #
-# behavior of this variable in the following ways #
-# * Default Value #
-# * Valid & Invalid values #
-# * Scope & Access method #
-# * Data Integrity #
-# #
-# Reference: (Not given on website) #
-# #
-###############################################################################
-
---source include/load_sysvars.inc
-####################################################################
-# START OF log_bin_trust_routine_creators TESTS #
-####################################################################
-
-
-#############################################################
-# Save initial value #
-#############################################################
-
-SET @start_global_value = @@global.log_bin_trust_routine_creators;
-SELECT @start_global_value;
-
-
---echo '#--------------------FN_DYNVARS_064_01-------------------------#'
-########################################################################
-# Display the DEFAULT value of log_bin_trust_routine_creators #
-########################################################################
-
-SET @@global.log_bin_trust_routine_creators = TRUE;
-SET @@global.log_bin_trust_routine_creators = DEFAULT;
-SELECT @@global.log_bin_trust_routine_creators;
-
-
---echo '#--------------------FN_DYNVARS_064_02-------------------------#'
-##############################################################################
-# Check the DEFAULT value of log_bin_trust_routine_creators #
-##############################################################################
-
-SET @@global.log_bin_trust_routine_creators = DEFAULT;
-SELECT @@global.log_bin_trust_routine_creators = 'FALSE';
-
-
---echo '#--------------------FN_DYNVARS_064_03-------------------------#'
-##################################################################
-# Change the value of variable to a valid value for GLOBAL Scope #
-##################################################################
-
-SET @@global.log_bin_trust_routine_creators = ON;
-SELECT @@global.log_bin_trust_routine_creators;
-SET @@global.log_bin_trust_routine_creators = OFF;
-SELECT @@global.log_bin_trust_routine_creators;
-SET @@global.log_bin_trust_routine_creators = 0;
-SELECT @@global.log_bin_trust_routine_creators;
-SET @@global.log_bin_trust_routine_creators = 1;
-SELECT @@global.log_bin_trust_routine_creators;
-SET @@global.log_bin_trust_routine_creators = TRUE;
-SELECT @@global.log_bin_trust_routine_creators;
-SET @@global.log_bin_trust_routine_creators = FALSE;
-SELECT @@global.log_bin_trust_routine_creators;
-
-
---echo '#-------------------FN_DYNVARS_064_04----------------------------#'
-###########################################################################
-# Test if accessing session log_bin_trust_routine_creators gives error #
-###########################################################################
-
---Error ER_GLOBAL_VARIABLE
-SET @@session.log_bin_trust_routine_creators = 0;
---Error ER_INCORRECT_GLOBAL_LOCAL_VAR
-SELECT @@session.log_bin_trust_routine_creators;
-
-
---echo '#------------------FN_DYNVARS_064_05-----------------------#'
-##########################################################################
-# Change the value of log_bin_trust_routine_creators to an invalid value #
-##########################################################################
-
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@global.log_bin_trust_routine_creators = 'ONN';
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@global.log_bin_trust_routine_creators = "OFFF";
-SET @@global.log_bin_trust_routine_creators = OF;
-SELECT @@global.log_bin_trust_routine_creators;
---echo 'Bug# 34828: OF is also working as OFF and no error is coming';
-
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@global.log_bin_trust_routine_creators = TTRUE;
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@global.log_bin_trust_routine_creators = FELSE;
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@global.log_bin_trust_routine_creators = -1024;
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@global.log_bin_trust_routine_creators = 65536;
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@global.log_bin_trust_routine_creators = 65530.34;
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@global.log_bin_trust_routine_creators = test;
-
-
---echo '#------------------FN_DYNVARS_064_06-----------------------#'
-###############################################################################
-# Check if the value in GLOBAL & SESSION Tables matches value in variable #
-###############################################################################
-
-
-SELECT @@global.log_bin_trust_routine_creators = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_bin_trust_routine_creators';
-
---Error ER_INCORRECT_GLOBAL_LOCAL_VAR
-SELECT @@session.log_bin_trust_routine_creators = VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='log_bin_trust_routine_creators';
-
-
---echo '#---------------------FN_DYNVARS_064_07----------------------#'
-#################################################################################
-# Check if accessing variable with and without GLOBAL point to same variable #
-#################################################################################
-
-
-SET @@global.log_bin_trust_routine_creators = TRUE;
-SELECT @@log_bin_trust_routine_creators = @@global.log_bin_trust_routine_creators;
-
-
---echo '#---------------------FN_DYNVARS_064_08----------------------#'
-###################################################################
-# Check if variable can be accessed with and without @@ sign #
-###################################################################
-
-SET @@global.log_bin_trust_routine_creators = TRUE;
-SELECT @@log_bin_trust_routine_creators;
---Error ER_UNKNOWN_TABLE
-SELECT local.log_bin_trust_routine_creators;
---Error ER_UNKNOWN_TABLE
-SELECT session.log_bin_trust_routine_creators;
---Error ER_BAD_FIELD_ERROR
-SELECT log_bin_trust_routine_creators = @@session.log_bin_trust_routine_creators;
-
-
-####################################
-# Restore initial value #
-####################################
-
-SET @@global.log_bin_trust_routine_creators = @start_global_value;
-SELECT @@global.log_bin_trust_routine_creators;
-
-
-###################################################################
-# END OF log_bin_trust_routine_creators TESTS #
-###################################################################
-
=== modified file 'mysql-test/t/union.test'
--- a/mysql-test/t/union.test 2008-09-10 10:40:14 +0000
+++ b/mysql-test/t/union.test 2008-09-10 12:50:02 +0000
@@ -93,64 +93,6 @@ SELECT @a:=1 UNION SELECT @a:=@a+1;
#
-# Bug#32858: Erro: "Incorrect usage of UNION and INTO" does not take subselects
-# into account
-#
-CREATE TABLE t1 (a INT);
-INSERT INTO t1 VALUES (1);
-
-SELECT a INTO @v FROM (
- SELECT a FROM t1
- UNION
- SELECT a FROM t1
-) alias;
-
-SELECT a INTO OUTFILE 'union.out.file' FROM (
- SELECT a FROM t1
- UNION
- SELECT a FROM t1 WHERE 0
-) alias;
-
-SELECT a INTO DUMPFILE 'union.out.file2' FROM (
- SELECT a FROM t1
- UNION
- SELECT a FROM t1 WHERE 0
-) alias;
-
-#
-# INTO will not be allowed in subqueries in version 5.1 and above.
-#
-SELECT a FROM (
- SELECT a FROM t1
- UNION
- SELECT a INTO @v FROM t1
-) alias;
-
-SELECT a FROM (
- SELECT a FROM t1
- UNION
- SELECT a INTO OUTFILE 'union.out.file3' FROM t1
-) alias;
-
-SELECT a FROM (
- SELECT a FROM t1
- UNION
- SELECT a INTO DUMPFILE 'union.out.file4' FROM t1
-) alias;
-
-SELECT a FROM t1 UNION SELECT a INTO @v FROM t1;
-SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1;
-SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1;
---error ER_WRONG_USAGE
-SELECT a INTO @v FROM t1 UNION SELECT a FROM t1;
---error ER_WRONG_USAGE
-SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1;
---error ER_WRONG_USAGE
-SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1;
-
-DROP TABLE t1;
-
-#
# Test bug reported by joc@presence-pc.com
#
=== modified file 'sql/backup/backup_aux.h'
--- a/sql/backup/backup_aux.h 2008-07-31 10:45:02 +0000
+++ b/sql/backup/backup_aux.h 2008-08-21 19:28:49 +0000
@@ -47,6 +47,12 @@ storage_engine_ref get_se_by_name(const
namespace backup {
/**
+ Constants for appending uniqueness to privileges in backup catalog.
+*/
+#define UNIQUE_PRIV_KEY_LEN 9
+#define UNIQUE_PRIV_KEY_FORMAT "%08lu"
+
+/**
Local version of LEX_STRING structure.
Defines various constructors for convenience.
=== modified file 'sql/backup/backup_info.cc'
--- a/sql/backup/backup_info.cc 2008-08-05 08:04:30 +0000
+++ b/sql/backup/backup_info.cc 2008-08-20 13:23:10 +0000
@@ -309,7 +309,7 @@ Backup_info::Dep_node::get_key(const uch
Backup_info::Backup_info(Backup_restore_ctx &ctx)
:m_ctx(ctx), m_state(Backup_info::ERROR), native_snapshots(8),
m_dep_list(NULL), m_dep_end(NULL),
- m_srout_end(NULL), m_view_end(NULL), m_trigger_end(NULL)
+ m_srout_end(NULL), m_view_end(NULL), m_trigger_end(NULL), m_event_end(NULL)
{
using namespace backup;
@@ -786,6 +786,18 @@ int Backup_info::add_db_items(Db &db)
if (add_objects(db, BSTREAM_IT_TRIGGER, *it))
goto error;
+ delete it;
+ it= get_all_db_grants(m_ctx.m_thd, &db.name());
+
+ if (!it)
+ {
+ m_ctx.fatal_error(ER_BACKUP_LIST_DB_PRIV, db.name().ptr());
+ goto error;
+ }
+
+ if (add_objects(db, BSTREAM_IT_PRIVILEGE, *it))
+ goto error;
+
goto finish;
error:
@@ -1002,7 +1014,7 @@ Backup_info::add_db_object(Db &db, const
ulong pos= db.obj_count();
DBUG_ASSERT(obj);
- const ::String *name= obj->get_name();
+ String *name= (String *)obj->get_name();
DBUG_ASSERT(name);
switch (type) {
@@ -1016,12 +1028,29 @@ Backup_info::add_db_object(Db &db, const
case BSTREAM_IT_SFUNC: error= ER_BACKUP_CATALOG_ADD_SROUT; break;
case BSTREAM_IT_EVENT: error= ER_BACKUP_CATALOG_ADD_EVENT; break;
case BSTREAM_IT_TRIGGER: error= ER_BACKUP_CATALOG_ADD_TRIGGER; break;
+ case BSTREAM_IT_PRIVILEGE: error= ER_BACKUP_CATALOG_ADD_PRIV; break;
// Only known types of objects should be added to the catalogue.
default: DBUG_ASSERT(FALSE);
}
+ /*
+ Generate a unique name for the privilege (grant) objects.
+ Note: this name does not alter the mechanics of the
+ grant objects in si_objects.cc
+ */
+ if (type == BSTREAM_IT_PRIVILEGE)
+ {
+ String new_name;
+ char buff[10];
+ sprintf(buff, UNIQUE_PRIV_KEY_FORMAT, pos);
+ new_name.append(*name);
+ new_name.append(" ");
+ new_name.append(buff);
+ name->copy(new_name);
+ }
+
/*
Add new object to the dependency list. If it is a view, add its
dependencies first.
@@ -1068,9 +1097,8 @@ Backup_info::add_db_object(Db &db, const
objects.
*/
- // Add object to catalogue
Dbobj *o= Image_info::add_db_object(db, type, *name, pos);
-
+
if (!o)
{
m_ctx.fatal_error(error, db.name().ptr(), name->ptr());
@@ -1199,6 +1227,12 @@ int Backup_info::add_to_dep_list(const o
break;
case BSTREAM_IT_EVENT:
+ end= &m_event_end;
+ if (!m_event_end)
+ m_event_end= m_trigger_end ? m_trigger_end : m_view_end ? m_view_end : m_srout_end;
+ break;
+
+ case BSTREAM_IT_PRIVILEGE:
end= &m_dep_end;
break;
=== modified file 'sql/backup/backup_info.h'
--- a/sql/backup/backup_info.h 2008-05-17 15:54:19 +0000
+++ b/sql/backup/backup_info.h 2008-08-20 13:23:10 +0000
@@ -141,6 +141,12 @@ class Backup_info: public backup::Image_
*/
Dep_node *m_trigger_end;
+ /**
+ Points at the last event on the dependency list. NULL if events section
+ is empty.
+ */
+ Dep_node *m_event_end;
+
/**
Hash keeping all elements stored in the dependency list.
=== modified file 'sql/backup/backup_test.cc'
--- a/sql/backup/backup_test.cc 2008-07-19 03:03:39 +0000
+++ b/sql/backup/backup_test.cc 2008-08-20 13:23:10 +0000
@@ -44,14 +44,20 @@ int execute_backup_test_command(THD *thd
field_list.push_back(new Item_empty_string("serialization", 13));
protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
- obs::ObjIterator *it= obs::get_databases(thd);
-
- if (it)
+ //obs::ObjIterator *it= obs::get_databases(thd);
+ List_iterator<LEX_STRING> it(*db_list);
+
+ //if (it)
{
obs::Obj *db;
- while ((db= it->next()))
+ //while ((db= it->next()))
+ LEX_STRING *dbname;
+ while ((dbname= it++))
{
+ String dir;
+ dir.copy(dbname->str, dbname->length, system_charset_info);
+ db= get_database(&dir);
if (is_internal_db_name(db->get_db_name()))
continue;
@@ -223,18 +229,42 @@ int execute_backup_test_command(THD *thd
delete event;
}
-
- delete tit;
}
- // That's it.
+ //
+ // List db grants.
+ //
+ tit= obs::get_all_db_grants(thd, db->get_name());
- delete db;
- }
- }
+ if (tit)
+ {
+ obs::Obj *grant;
+
+ while ((grant= tit->next()))
+ {
+ String serial;
+ serial.length(0);
+ protocol->prepare_for_resend();
+ protocol->store(const_cast<String*>(db->get_name()));
+ protocol->store(const_cast<String*>(grant->get_name()));
+ String user;
+ String host;
+ String *user_host= (String *)grant->get_name();
+ user_exists(thd, user_host);
+ protocol->store(C_STRING_WITH_LEN("GRANT"),
+ system_charset_info);
+ grant->serialize(thd, &serial);
+ protocol->store(&serial);
+ protocol->write();
- delete it;
+ delete grant;
+ }
+ delete tit;
+ }
+ }
+ }
+ thd->main_da.reset_diagnostics_area();
my_eof(thd);
DBUG_RETURN(res);
}
=== modified file 'sql/backup/be_default.cc'
--- a/sql/backup/be_default.cc 2008-07-09 08:19:03 +0000
+++ b/sql/backup/be_default.cc 2008-08-18 08:25:56 +0000
@@ -381,6 +381,14 @@ result_t Backup::get_data(Buffer &buf)
read_set= cur_table->read_set;
start_tbl_read(cur_table);
+ // The first time the table is accessed after opening it,
+ // cur_table->in_use points to the locking thread. It has to point
+ // to the backup thread before the table can be read
+ if (cur_table->in_use != locking_thd->m_thd) {
+ DBUG_ASSERT(cur_table->in_use == locking_thd->lock_thd);
+ cur_table->in_use= locking_thd->m_thd;
+ }
+
buf.table_num= tbl_num;
mode= READ_RCD;
}
=== modified file 'sql/backup/image_info.cc'
--- a/sql/backup/image_info.cc 2008-07-31 10:45:02 +0000
+++ b/sql/backup/image_info.cc 2008-08-20 13:23:10 +0000
@@ -384,6 +384,7 @@ Image_info::Obj *find_obj(const Image_in
case BSTREAM_IT_SFUNC:
case BSTREAM_IT_EVENT:
case BSTREAM_IT_TRIGGER:
+ case BSTREAM_IT_PRIVILEGE:
{
const st_bstream_dbitem_info &it=
reinterpret_cast<const st_bstream_dbitem_info&>(item);
=== modified file 'sql/backup/image_info.h'
--- a/sql/backup/image_info.h 2008-08-11 16:06:30 +0000
+++ b/sql/backup/image_info.h 2008-08-20 13:23:10 +0000
@@ -1012,6 +1012,17 @@ obs::Obj* Image_info::Dbobj::materialize
case BSTREAM_IT_TRIGGER:
m_obj_ptr= obs::materialize_trigger(db_name, name, ver, &sdata);
break;
+ case BSTREAM_IT_PRIVILEGE:
+ {
+ /*
+ Here we undo the uniqueness suffix for grants.
+ */
+ String new_name;
+ new_name.copy(*name);
+ new_name.length(new_name.length() - UNIQUE_PRIV_KEY_LEN);
+ m_obj_ptr= obs::materialize_db_grant(db_name, &new_name, ver, &sdata);
+ break;
+ }
default: m_obj_ptr= NULL;
}
=== modified file 'sql/backup/kernel.cc'
--- a/sql/backup/kernel.cc 2008-08-11 16:06:30 +0000
+++ b/sql/backup/kernel.cc 2008-08-21 11:36:09 +0000
@@ -905,6 +905,7 @@ int Backup_restore_ctx::do_backup()
report_stats_pre(info);
DBUG_PRINT("backup",("Writing preamble"));
+ DEBUG_SYNC(m_thd, "backup_before_write_preamble");
if (write_preamble(info, s))
{
@@ -1053,6 +1054,10 @@ int Backup_restore_ctx::do_restore()
if (read_meta_data(info, s))
{
+ // FIXME: detect errors.
+ // FIXME: error logging.
+ m_thd->main_da.reset_diagnostics_area();
+
fatal_error(ER_BACKUP_READ_META);
DBUG_RETURN(m_error);
}
@@ -1427,6 +1432,7 @@ int bcat_add_item(st_bstream_image_heade
case BSTREAM_IT_SFUNC:
case BSTREAM_IT_EVENT:
case BSTREAM_IT_TRIGGER:
+ case BSTREAM_IT_PRIVILEGE:
{
st_bstream_dbitem_info *it= (st_bstream_dbitem_info*)item;
@@ -1438,7 +1444,6 @@ int bcat_add_item(st_bstream_image_heade
Image_info::Dbobj *it1= info->add_db_object(*db, item->type, name_str,
item->pos);
-
if (!it1)
return BSTREAM_ERROR;
@@ -1689,6 +1694,7 @@ int bcat_create_item(st_bstream_image_he
case BSTREAM_IT_EVENT: create_err= ER_BACKUP_CANT_RESTORE_EVENT; break;
case BSTREAM_IT_TRIGGER: create_err= ER_BACKUP_CANT_RESTORE_TRIGGER; break;
case BSTREAM_IT_TABLESPACE: create_err= ER_BACKUP_CANT_RESTORE_TS; break;
+ case BSTREAM_IT_PRIVILEGE: create_err= ER_BACKUP_CANT_RESTORE_PRIV; break;
/*
TODO: Decide what to do when we come across unknown item:
@@ -1775,6 +1781,48 @@ int bcat_create_item(st_bstream_image_he
// Create the object.
+ /*
+ We need to check to see if the user exists (grantee) and if not,
+ do not execute the grant.
+ */
+ if (item->type == BSTREAM_IT_PRIVILEGE)
+ {
+ /*
+ Issue warning to the user that grant was skipped.
+
+ @todo Replace write_message() call with the result of the revised
+ error handling work in WL#4384 with possible implementation
+ via a related bug report.
+ */
+ if (!obs::user_exists(thd, sobj->get_name()))
+ {
+ info->m_ctx.write_message(log_level::WARNING,
+ ER(ER_BACKUP_GRANT_SKIPPED),
+ create_stmt);
+ return BSTREAM_OK;
+ }
+ /*
+ We need to check the grant against the database list to ensure the
+ grants have not been altered to apply to another database.
+ */
+ ::String db_name; // db name extracted from grant statement
+ char *start;
+ char *end;
+ int size= 0;
+
+ start= strstr((char *)create_stmt.begin, "ON ") + 3;
+ end= strstr(start, ".");
+ size= end - start;
+ db_name.alloc(size);
+ db_name.length(0);
+ db_name.append(start, size);
+ if (!info->has_db(db_name))
+ {
+ info->m_ctx.fatal_error(ER_BACKUP_GRANT_WRONG_DB, create_stmt);
+ return BSTREAM_ERROR;
+ }
+ }
+
if (sobj->execute(thd))
{
info->m_ctx.fatal_error(create_err, desc);
@@ -1820,6 +1868,7 @@ int bcat_get_item_create_query(st_bstrea
case BSTREAM_IT_EVENT: meta_err= ER_BACKUP_GET_META_EVENT; break;
case BSTREAM_IT_TRIGGER: meta_err= ER_BACKUP_GET_META_TRIGGER; break;
case BSTREAM_IT_TABLESPACE: meta_err= ER_BACKUP_GET_META_TS; break;
+ case BSTREAM_IT_PRIVILEGE: meta_err= ER_BACKUP_GET_META_PRIV; break;
/*
This can't happen - the item was obtained from the backup kernel.
=== modified file 'sql/ddl_blocker.cc'
--- a/sql/ddl_blocker.cc 2008-06-25 13:39:04 +0000
+++ b/sql/ddl_blocker.cc 2008-08-19 15:35:29 +0000
@@ -101,29 +101,49 @@ void DDL_blocker_class::end_DDL()
/**
check_DDL_blocker
- Check to see if we are blocked from continuing. If so,
- wait until the blocked process signals the condition.
+ Check to see if we are blocked from continuing. If so, wait until block is
+ removed or the timeout specified by backup_wait_timeout variable occurs.
+
+ @param[in] thd The THD object from the caller.
- @param thd The THD object from the caller.
- @returns TRUE
+ @note: This operation blocks DDL operations until end_ddl() is called.
+
+ @returns TRUE if not blocked
+ @returns FALSE if ddl is blocked and timeout occurs
*/
my_bool DDL_blocker_class::check_DDL_blocker(THD *thd)
{
+ int ret = 0;
+ struct timespec ddl_timeout;
DBUG_ENTER("check_DDL_blocker()");
DEBUG_SYNC(thd, "before_check_ddl_blocked");
+ set_timespec(ddl_timeout, thd->backup_wait_timeout);
+
/*
Check the ddl blocker condition. Rest until ddl blocker is released.
*/
pthread_mutex_lock(&THR_LOCK_DDL_is_blocked);
thd->enter_cond(&COND_DDL_blocker, &THR_LOCK_DDL_is_blocked,
"DDL blocker: DDL is blocked");
- while (DDL_blocked && !thd->DDL_exception)
- pthread_cond_wait(&COND_DDL_blocker, &THR_LOCK_DDL_is_blocked);
- start_DDL();
- thd->exit_cond("DDL blocker: Ok to run DDL");
- DEBUG_SYNC(thd, "after_start_ddl");
- DBUG_RETURN(TRUE);
+ while (DDL_blocked && !thd->DDL_exception && (ret == 0))
+ {
+ if (thd->backup_wait_timeout == 0)
+ ret = -1;
+ else
+ ret= pthread_cond_timedwait(&COND_DDL_blocker, &THR_LOCK_DDL_is_blocked,
+ &ddl_timeout);
+ }
+ thd->exit_cond("DDL blocker: DDL is not blocked");
+ if (ret == 0)
+ {
+ start_DDL();
+ DEBUG_SYNC(thd, "after_start_ddl");
+ }
+ else
+ my_error(ER_DDL_TIMEOUT, MYF(0), thd->query);
+
+ DBUG_RETURN(ret == 0);
}
/**
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2008-08-27 16:48:24 +0000
+++ b/sql/mysql_priv.h 2008-09-04 13:46:04 +0000
@@ -638,6 +638,8 @@ extern void debug_sync(THD *thd, const c
#define DEBUG_SYNC(_thd_, _sync_point_name_) /* disabled DEBUG_SYNC */
#endif /* defined(ENABLED_DEBUG_SYNC) */
+#define BACKUP_WAIT_TIMEOUT_DEFAULT 50;
+
/* BINLOG_DUMP options */
#define BINLOG_DUMP_NON_BLOCK 1
=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc 2008-09-09 12:48:29 +0000
+++ b/sql/set_var.cc 2008-09-10 12:50:02 +0000
@@ -230,6 +230,7 @@ static sys_var_long_ptr sys_concurrent_i
static sys_var_long_ptr sys_connect_timeout(&vars, "connect_timeout",
&connect_timeout);
static sys_var_const_str sys_datadir(&vars, "datadir", mysql_real_data_home);
+static sys_var_backup_wait_timeout sys_backup_wait_timeout(&vars, "backup_wait_timeout");
#ifndef DBUG_OFF
static sys_var_thd_dbug sys_dbug(&vars, "debug");
#endif
@@ -2851,6 +2852,61 @@ bool sys_var_insert_id::update(THD *thd,
}
+/**
+ Get value.
+
+ Returns the value for the backup_wait_timeout session variable.
+
+ @param[IN] thd Thread object
+ @param[IN] type Type of variable
+ @param[IN] base Not used
+
+ @returns value of variable
+*/
+uchar *sys_var_backup_wait_timeout::value_ptr(THD *thd, enum_var_type type,
+ LEX_STRING *base)
+{
+ thd->sys_var_tmp.ulong_value= thd->backup_wait_timeout;
+ return (uchar*) &thd->sys_var_tmp.ulonglong_value;
+}
+
+
+/**
+ Update value.
+
+ Set the backup_wait_timeout variable.
+
+ @param[IN] thd Thread object
+ @param[IN] var Pointer to value from command.
+
+ @returns 0
+*/
+bool sys_var_backup_wait_timeout::update(THD *thd, set_var *var)
+{
+ if (var->save_result.ulong_value > (LONG_MAX/1000))
+ thd->backup_wait_timeout= LONG_MAX/1000;
+ else
+ thd->backup_wait_timeout= var->save_result.ulong_value;
+ return 0;
+}
+
+
+/**
+ Set default value.
+
+ Set the backup_wait_timeout variable to the default value.
+
+ @param[IN] thd Thread object
+ @param[IN] type Type of variable
+
+ @returns 0
+*/
+void sys_var_backup_wait_timeout::set_default(THD *thd, enum_var_type type)
+{
+ thd->backup_wait_timeout= BACKUP_WAIT_TIMEOUT_DEFAULT;
+}
+
+
uchar *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type,
LEX_STRING *base)
{
=== modified file 'sql/set_var.h'
--- a/sql/set_var.h 2008-09-09 12:48:29 +0000
+++ b/sql/set_var.h 2008-09-10 12:50:02 +0000
@@ -655,6 +655,31 @@ public:
};
+/**
+ Backup_wait_timeout system variable class.
+
+ This class consolidates the mechanism to manage the backup_wait_timeout
+ system variable. It is a session only variable thus we check the type for
+ check_type() and check_default() to ensure it isn't accessed as a global.
+
+ A set_default() method is provided to allow the SET command :
+ SET backup_wait_TIMEOUT = DEFAULT;
+*/
+class sys_var_backup_wait_timeout :public sys_var
+{
+public:
+ sys_var_backup_wait_timeout(sys_var_chain *chain, const char *name_arg)
+ :sys_var(name_arg)
+ { chain_sys_var(chain); }
+ bool update(THD *thd, set_var *var);
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+ bool check_default(enum_var_type type) { return type == OPT_GLOBAL; }
+ SHOW_TYPE show_type() { return SHOW_LONG; }
+ uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+ void set_default(THD *thd, enum_var_type type);
+};
+
+
class sys_var_insert_id :public sys_var
{
public:
=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt 2008-08-22 13:21:31 +0000
+++ b/sql/share/errmsg.txt 2008-08-27 13:03:26 +0000
@@ -6275,7 +6275,7 @@ ER_BACKUP_CANT_RESTORE_DB
ER_BACKUP_CANT_RESTORE_TABLE
eng "Could not restore table %-.64s"
ER_BACKUP_CANT_RESTORE_VIEW
- eng "Could not restore view %-.64s"
+ eng "Could not restore view %-.64s. Please check the view definition for possible missing dependencies."
ER_BACKUP_CANT_RESTORE_SROUT
eng "Could not restore stored routine %-.64s"
ER_BACKUP_CANT_RESTORE_EVENT
@@ -6374,3 +6374,17 @@ ER_BACKUP_RELEASE_NAME_LOCK_FAILED
eng "Restore failed to release the name locks on the tables."
ER_BACKUP_BACKUPDIR
eng "The path specified for the system variable backupdir cannot be accessed or is invalid. ref: %-.64s"
+ER_DDL_TIMEOUT
+ eng "The backup wait timeout has expired for query '%-64s'."
+ER_BACKUP_LIST_DB_PRIV
+ eng "Can't enumerate grants in database '%-.64s'."
+ER_BACKUP_CATALOG_ADD_PRIV
+ eng "Failed to add grant '%-.64s' to the catalog"
+ER_BACKUP_GET_META_PRIV
+ eng "Failed to obtain meta-data for grant '%-.64s'."
+ER_BACKUP_CANT_RESTORE_PRIV
+ eng "Could not execute grant '%-.64s'."
+ER_BACKUP_GRANT_SKIPPED
+ eng "The grant '%-.64s' was skipped because the user does not exist."
+ER_BACKUP_GRANT_WRONG_DB
+ eng "The grant '%-.64s' failed. Database not included in the backup image."
=== modified file 'sql/si_objects.cc'
--- a/sql/si_objects.cc 2008-08-11 10:41:41 +0000
+++ b/sql/si_objects.cc 2008-08-21 11:36:09 +0000
@@ -759,6 +759,123 @@ private:
String m_create_stmt;
};
+/**
+ @class DbGrantObj
+
+ This class provides an abstraction to database-level grants.
+ This class will permit the recording and replaying of these
+ grants.
+*/
+class DbGrantObj : public Obj
+{
+public:
+ DbGrantObj(const String *grantee,
+ const String *db_name,
+ const String *priv_type);
+
+public:
+ virtual bool materialize(uint serialization_version,
+ const String *serialization);
+
+ const String* get_name()
+ {
+ return &m_name;
+ }
+
+ const String *get_db_name()
+ {
+ return &m_db_name;
+ }
+
+ const String *get_priv_type()
+ {
+ return &m_priv_type;
+ }
+
+protected:
+ // These attributes are to be used only for serialization.
+ String m_db_name; ///< corresponds with TABLE_SCHEMA in IS tables.
+ String m_name; ///< name used to list in catalog.
+ String m_grantee; ///< corresponds with GRANTEE in IS tables.
+ String m_priv_type; ///< corresponds with PRIVILEGE_TYPE in IS tables.
+
+ bool drop(THD *thd) { return 0; }; // Drop not supported.
+ virtual bool do_execute(THD *thd);
+
+private:
+ virtual bool do_serialize(THD *thd, String *serialization);
+ // These attributes are to be used only for materialization.
+ String m_grant_stmt;
+};
+
+/**
+ @class TblGrantObj
+
+ This class provides an abstraction to table-level and routine-level grants.
+ This class will permit the recording and replaying of these
+ grants.
+*/
+class TblGrantObj : public DbGrantObj
+{
+public:
+ TblGrantObj(const String *grantee,
+ const String *db_name,
+ const String *table_name,
+ const String *priv_type);
+
+public:
+
+ const String *get_table_name()
+ {
+ return &m_table_name;
+ }
+
+protected:
+ // These attributes are to be used only for serialization.
+ String m_table_name; ///< corresponds with TABLE_NAME in IS tables.
+
+
+private:
+ virtual bool do_serialize(THD *thd, String *serialization);
+
+ // These attributes are to be used only for materialization.
+ String m_grant_stmt;
+};
+
+/**
+ @class ColGrantObj
+
+ This class provides an abstraction to column-level grants.
+ This class will permit the recording and replaying of these
+ grants.
+*/
+class ColGrantObj : public TblGrantObj
+{
+public:
+ ColGrantObj(const String *grantee,
+ const String *db_name,
+ const String *table_name,
+ const String *col_name,
+ const String *priv_type);
+
+public:
+
+ const String *get_col_name()
+ {
+ return &m_col_name;
+ }
+
+protected:
+ // These attributes are to be used only for serialization.
+ String m_col_name; ///< corresponds with COLUMN_NAME in IS tables.
+
+private:
+ virtual bool do_serialize(THD *thd, String *serialization);
+
+ // These attributes are to be used only for materialization.
+ String m_grant_stmt;
+};
+
///////////////////////////////////////////////////////////////////////////
//
@@ -797,9 +914,9 @@ public:
protected:
virtual Obj *create_obj(TABLE *t) = 0;
+ THD *m_thd;
private:
- THD *m_thd;
TABLE *m_is_table;
handler *m_ha;
my_bitmap_map *m_orig_columns;
@@ -938,6 +1055,67 @@ private:
String m_db_name;
};
+class DbGrantIterator : public InformationSchemaIterator
+{
+public:
+ DbGrantIterator(THD *thd,
+ const String *db_name,
+ TABLE *is_table,
+ handler *ha,
+ my_bitmap_map *orig_columns) :
+ InformationSchemaIterator(thd, is_table, ha, orig_columns)
+ {
+ m_db_name.copy(*db_name);
+ }
+
+protected:
+ virtual DbGrantObj *create_obj(TABLE *t);
+
+private:
+ String m_db_name;
+};
+
+class TblGrantIterator : public InformationSchemaIterator
+{
+public:
+ TblGrantIterator(THD *thd,
+ const String *db_name,
+ TABLE *is_table,
+ handler *ha,
+ my_bitmap_map *orig_columns) :
+ InformationSchemaIterator(thd, is_table, ha, orig_columns)
+ {
+ m_db_name.copy(*db_name);
+ }
+
+protected:
+ virtual TblGrantObj *create_obj(TABLE *t);
+
+private:
+ String m_db_name;
+};
+
+class ColGrantIterator : public InformationSchemaIterator
+{
+public:
+ ColGrantIterator(THD *thd,
+ const String *db_name,
+ TABLE *is_table,
+ handler *ha,
+ my_bitmap_map *orig_columns) :
+ InformationSchemaIterator(thd, is_table, ha, orig_columns)
+ {
+ m_db_name.copy(*db_name);
+ }
+
+protected:
+ virtual ColGrantObj *create_obj(TABLE *t);
+
+private:
+ String m_db_name;
+};
+
+
///////////////////////////////////////////////////////////////////////////
class DbStoredFuncIterator : public DbStoredProcIterator
@@ -1055,6 +1233,24 @@ bool InformationSchemaIterator::prepare_
*is_table= open_schema_table(thd, st, NULL);
break;
}
+ case SCH_SCHEMA_PRIVILEGES:
+ {
+ st= find_schema_table(thd, "SCHEMA_PRIVILEGES");
+ *is_table= open_schema_table(thd, st, NULL);
+ break;
+ }
+ case SCH_TABLE_PRIVILEGES:
+ {
+ st= find_schema_table(thd, "TABLE_PRIVILEGES");
+ *is_table= open_schema_table(thd, st, NULL);
+ break;
+ }
+ case SCH_COLUMN_PRIVILEGES:
+ {
+ st= find_schema_table(thd, "COLUMN_PRIVILEGES");
+ *is_table= open_schema_table(thd, st, NULL);
+ break;
+ }
default:
{
st= get_schema_table(is_table_idx);
@@ -1320,6 +1516,141 @@ EventObj *DbEventIterator::create_obj(TA
return new EventObj(&db_name, &event_name);
}
#endif
+
+///////////////////////////////////////////////////////////////////////////
+
+//
+// Implementation: DbGrantIterator class.
+//
+
+///////////////////////////////////////////////////////////////////////////
+
+DbGrantObj* DbGrantIterator::create_obj(TABLE *t)
+{
+ String grantee; // corresponds with GRANTEE
+ String db_name; // corresponds with TABLE_SCHEMA
+ String priv_type; // corresponds with PRIVILEGE_TYPE
+
+ t->field[0]->val_str(&grantee);
+ t->field[2]->val_str(&db_name);
+ t->field[3]->val_str(&priv_type);
+
+ /*
+ The fill method for SCHEMA_PRIVILEGES does not use the COND portion
+ of the generic fill() method. Thus, we have to do the restriction here.
+
+ Ensure the only rows sent back from iterator are the ones that match the
+ database specified.
+ */
+ if (db_name == m_db_name)
+ {
+ DBUG_PRINT("DbGrantIterator::create", (" Found grant %s %s %s",
+ db_name.ptr(), grantee.ptr(), priv_type.ptr()));
+
+ /*
+ Include grants for only users that exist at time of backup.
+ */
+ if (user_exists(m_thd, &grantee))
+ return new DbGrantObj(&grantee, &db_name, &priv_type);
+ else
+ return NULL;
+ }
+ else
+ return NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+//
+// Implementation: TblGrantIterator class.
+//
+
+///////////////////////////////////////////////////////////////////////////
+
+TblGrantObj* TblGrantIterator::create_obj(TABLE *t)
+{
+ String grantee; // corresponds with GRANTEE
+ String db_name; // corresponds with TABLE_SCHEMA
+ String tbl_name; // corresponds with TABLE_NAME
+ String priv_type; // corresponds with PRIVILEGE_TYPE
+
+ t->field[0]->val_str(&grantee);
+ t->field[2]->val_str(&db_name);
+ t->field[3]->val_str(&tbl_name);
+ t->field[4]->val_str(&priv_type);
+
+ /*
+ The fill method for TABLE_PRIVILEGES does not use the COND portion
+ of the generic fill() method. Thus, we have to do the restriction here.
+
+ Ensure the only rows sent back from iterator are the ones that match the
+ database specified.
+ */
+ if (db_name == m_db_name)
+ {
+ DBUG_PRINT("TblGrantIterator::create", (" Found grant %s %s %s %s",
+ db_name.ptr(), grantee.ptr(), tbl_name.ptr(), priv_type.ptr()));
+
+ /*
+ Include grants for only users that exist at time of backup.
+ */
+ if (user_exists(m_thd, &grantee))
+ return new TblGrantObj(&grantee, &db_name, &tbl_name, &priv_type);
+ else
+ return NULL;
+ }
+ else
+ return NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+//
+// Implementation: ColGrantIterator class.
+//
+
+///////////////////////////////////////////////////////////////////////////
+
+ColGrantObj* ColGrantIterator::create_obj(TABLE *t)
+{
+ String grantee; // corresponds with GRANTEE
+ String db_name; // corresponds with TABLE_SCHEMA
+ String tbl_name; // corresponds with TABLE_NAME
+ String col_name; // corresponds with COLUMN_NAME
+ String priv_type; // corresponds with PRIVILEGE_TYPE
+
+ t->field[0]->val_str(&grantee);
+ t->field[2]->val_str(&db_name);
+ t->field[3]->val_str(&tbl_name);
+ t->field[4]->val_str(&col_name);
+ t->field[5]->val_str(&priv_type);
+
+ /*
+ The fill method for COLUMN_PRIVILEGES does not use the COND portion
+ of the generic fill() method. Thus, we have to do the restriction here.
+
+ Ensure the only rows sent back from iterator are the ones that match the
+ database specified.
+ */
+ if (db_name == m_db_name)
+ {
+ DBUG_PRINT("ColGrantIterator::create", (" Found grant %s %s %s %s %s",
+ db_name.ptr(), grantee.ptr(), tbl_name.ptr(), col_name.ptr(),
+ priv_type.ptr()));
+
+ /*
+ Include grants for only users that exist at time of backup.
+ */
+ if (user_exists(m_thd, &grantee))
+ return new ColGrantObj(&grantee, &db_name, &tbl_name,
+ &col_name, &priv_type);
+ else
+ return NULL;
+ }
+ else
+ return NULL;
+}
+
///////////////////////////////////////////////////////////////////////////
//
@@ -1502,6 +1833,18 @@ DbEventIterator *
create_is_iterator<DbEventIterator>(THD *, enum_schema_tables, const String *);
#endif
+template
+DbGrantIterator *
+create_is_iterator<DbGrantIterator>(THD *, enum_schema_tables, const String *);
+
+template
+TblGrantIterator *
+create_is_iterator<TblGrantIterator>(THD *, enum_schema_tables, const String *);
+
+template
+ColGrantIterator *
+create_is_iterator<ColGrantIterator>(THD *, enum_schema_tables, const String *);
+
ObjIterator *get_db_tables(THD *thd, const String *db_name)
{
return create_is_iterator<DbTablesIterator>(thd, SCH_TABLES, db_name);
@@ -1536,6 +1879,56 @@ ObjIterator *get_db_events(THD *thd, con
#endif
}
+/**
+ GrantObjIterator constructor
+
+ This constructor initializes iterators for the grants supported.
+ These include database-, table- and routine-, and column-level grants.
+ The iterators return all of the grants for the database specified.
+*/
+GrantObjIterator::GrantObjIterator(THD *thd, const String *db_name)
+: ObjIterator()
+{
+ db_grants= create_is_iterator<DbGrantIterator>(thd,
+ SCH_SCHEMA_PRIVILEGES,
+ db_name);
+ tbl_grants= create_is_iterator<TblGrantIterator>(thd,
+ SCH_TABLE_PRIVILEGES,
+ db_name);
+ col_grants= create_is_iterator<ColGrantIterator>(thd,
+ SCH_COLUMN_PRIVILEGES,
+ db_name);
+}
+
+Obj *GrantObjIterator::next()
+{
+ Obj *obj= 0;
+ obj= db_grants->next();
+ if (!obj)
+ obj= tbl_grants->next();
+ if (!obj)
+ obj= col_grants->next();
+ return obj;
+}
+
+/**
+ Creates a high-level iterator that iterates over database-, table-,
+ routine-, and column-level privileges which shall permit a single
+ iterator from the si_objects to retrieve all of the privileges for
+ a given database.
+
+ @param[IN] thd Current THD object
+ @param[IN] db_name Name of database to get grants
+
+ @Note The client is responsible for destroying the returned iterator.
+
+ @return a pointer to an iterator object.
+ @retval NULL in case of error.
+*/
+ObjIterator *get_all_db_grants(THD *thd, const String *db_name)
+{
+ return new GrantObjIterator(thd, db_name);
+}
///////////////////////////////////////////////////////////////////////////
@@ -1607,7 +2000,7 @@ bool DatabaseObj::do_serialize(THD *thd,
if (check_db_dir_existence(m_db_name.c_ptr()))
{
my_error(ER_BAD_DB_ERROR, MYF(0), m_db_name.c_ptr());
- DBUG_RETURN(FALSE);
+ DBUG_RETURN(TRUE);
}
load_db_opt_by_name(thd, m_db_name.c_ptr(), &create);
@@ -1941,8 +2334,9 @@ bool TriggerObj::do_serialize(THD *thd,
alloc_mdl_locks(lst, thd->mem_root);
+ DBUG_EXECUTE_IF("backup_fail_add_trigger", DBUG_RETURN(TRUE););
if (open_tables(thd, &lst, &num_tables, 0))
- DBUG_RETURN(FALSE);
+ DBUG_RETURN(TRUE);
DBUG_ASSERT(num_tables == 1);
Table_triggers_list *triggers= lst->table->triggers;
@@ -2584,6 +2978,191 @@ bool TablespaceObj::do_execute(THD *thd)
}
///////////////////////////////////////////////////////////////////////////
+//
+// Implementation: DbGrantObj class.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+DbGrantObj::DbGrantObj(const String *grantee,
+ const String *db_name,
+ const String *priv_type)
+{
+ // copy strings to newly allocated memory
+ m_db_name.copy(*db_name);
+ m_grantee.copy(*grantee);
+ m_name.copy(*grantee);
+ m_priv_type.copy(*priv_type);
+}
+
+/**
+ Serialize the object.
+
+ This method produces the data necessary for materializing the object
+ on restore (creates object).
+
+ @param[in] thd Thread context.
+ @param[out] serialization The data needed to recreate this object.
+
+ @note this method will return an error if the db_name is either
+ mysql or information_schema as these are not objects that
+ should be recreated using this interface.
+
+ @returns Error status.
+ @retval FALSE on success
+ @retval TRUE on error
+*/
+bool DbGrantObj::do_serialize(THD *thd, String *serialization)
+{
+ DBUG_ENTER("DbGrantObj::do_serialize()");
+ serialization->length(0);
+ serialization->append("GRANT ");
+ serialization->append(m_priv_type);
+ serialization->append(" ON ");
+ serialization->append(m_db_name);
+ serialization->append(".* TO ");
+ serialization->append(m_grantee);
+ DBUG_RETURN(0);
+}
+
+/**
+ Materialize the serialization string.
+
+ This method saves serialization string into a member variable.
+
+ @param[in] serialization_version version number of this interface
+ @param[in] serialization the string from serialize()
+
+ @todo take serialization_version into account
+
+ @returns Error status.
+ @retval FALSE on success
+ @retval TRUE on error
+*/
+bool DbGrantObj::materialize(uint serialization_version,
+ const String *serialization)
+{
+ DBUG_ENTER("DbGrantObj::materialize()");
+ m_grant_stmt.copy(*serialization);
+ DBUG_RETURN(0);
+}
+
+/**
+ Create the object.
+
+ This method uses serialization string in a query and executes it.
+
+ @param[in] thd Thread context.
+
+ @returns Error status.
+ @retval FALSE on success
+ @retval TRUE on error
+*/
+bool DbGrantObj::do_execute(THD *thd)
+{
+ DBUG_ENTER("DbGrantObj::do_execute()");
+ DBUG_RETURN(execute_with_ctx(thd, &m_grant_stmt, true));
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Implementation: TblGrantObj class.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+TblGrantObj::TblGrantObj(const String *grantee,
+ const String *db_name,
+ const String *table_name,
+ const String *priv_type)
+: DbGrantObj(grantee, db_name, priv_type)
+{
+ // copy strings to newly allocated memory
+ m_table_name.copy(*table_name);
+}
+
+/**
+ Serialize the object.
+
+ This method produces the data necessary for materializing the object
+ on restore (creates object).
+
+ @param[in] thd Thread context.
+ @param[out] serialization The data needed to recreate this object.
+
+ @note this method will return an error if the db_name is either
+ mysql or information_schema as these are not objects that
+ should be recreated using this interface.
+
+ @returns Error status.
+ @retval FALSE on success
+ @retval TRUE on error
+*/
+bool TblGrantObj::do_serialize(THD *thd, String *serialization)
+{
+ DBUG_ENTER("TblGrantObj::do_serialize()");
+ serialization->length(0);
+ serialization->append("GRANT ");
+ serialization->append(m_priv_type);
+ serialization->append(" ON ");
+ serialization->append(m_db_name);
+ serialization->append(".");
+ serialization->append(m_table_name);
+ serialization->append(" TO ");
+ serialization->append(m_grantee);
+ DBUG_RETURN(0);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Implementation: ColGrantObj class.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+ColGrantObj::ColGrantObj(const String *grantee,
+ const String *db_name,
+ const String *table_name,
+ const String *col_name,
+ const String *priv_type)
+: TblGrantObj(grantee, db_name, table_name, priv_type)
+{
+ // copy strings to newly allocated memory
+ m_col_name.copy(*col_name);
+}
+
+/**
+ Serialize the object.
+
+ This method produces the data necessary for materializing the object
+ on restore (creates object).
+
+ @param[in] thd Thread context.
+ @param[out] serialization The data needed to recreate this object.
+
+ @note this method will return an error if the db_name is either
+ mysql or information_schema as these are not objects that
+ should be recreated using this interface.
+
+ @returns Error status.
+ @retval FALSE on success
+ @retval TRUE on error
+*/
+bool ColGrantObj::do_serialize(THD *thd, String *serialization)
+{
+ DBUG_ENTER("ColGrantObj::do_serialize()");
+ serialization->length(0);
+ serialization->append("GRANT ");
+ serialization->append(m_priv_type);
+ serialization->append("(");
+ serialization->append(m_col_name);
+ serialization->append(") ON ");
+ serialization->append(m_db_name);
+ serialization->append(".");
+ serialization->append(m_table_name);
+ serialization->append(" TO ");
+ serialization->append(m_grantee);
+ DBUG_RETURN(0);
+}
+
+///////////////////////////////////////////////////////////////////////////
Obj *get_database(const String *db_name)
{
@@ -2721,6 +3300,33 @@ Obj *materialize_tablespace(const String
return obj;
}
+Obj *get_db_grant(const String *grantee,
+ const String *db_name)
+{
+ String priv_type;
+ priv_type.length(0);
+
+ return new DbGrantObj(grantee, db_name, &priv_type);
+}
+
+Obj *materialize_db_grant(const String *db_name,
+ const String *grantee,
+ uint serialization_version,
+ const String *serialization)
+{
+ /*
+ Here we create a grant for the purposes of applying the
+ grants. We use DbGrantObj for all types of grants because
+ we only have the GRANT statement in the serialization
+ string and therefore do not that the 'parts' to create
+ the specific types.
+ */
+ Obj *obj= get_db_grant(grantee, db_name);
+ obj->materialize(serialization_version, serialization);
+
+ return obj;
+}
+
///////////////////////////////////////////////////////////////////////////
bool is_internal_db_name(const String *db_name)
@@ -2744,6 +3350,90 @@ bool check_db_existence(const String *db
return check_db_dir_existence(((String *) db_name)->c_ptr_safe());
}
+/*
+ Splits grantee clause into user and host portions. Needed for checking
+ to see if user exists on system.
+*/
+int split_user_host(String *grantee, String *user, String *host)
+{
+ int len= 0;
+ int tics= 0;
+ char *ptr= 0;
+
+ /*
+ Since passwords are single byte characters and usernames can be multibyte
+ characters and the 0x40 = 64 = @ can occur in the username, we must search
+ for the first @ from the right.
+ */
+ len= grantee->length();
+ len--;
+ ptr= grantee->c_ptr() + len;
+ while ((len > 0) && (*ptr != '@'))
+ {
+ len--;
+ ptr= grantee->c_ptr() + len;
+ }
+
+ if (ptr == 0)
+ return -1;
+ len= ptr - grantee->c_ptr();
+ user->length(0);
+ char *cptr= grantee->c_ptr();
+
+ /*
+ String ' from strings.
+ */
+ if (strncmp(cptr, "'", 1) == 0)
+ {
+ cptr++;
+ len--;
+ tics++;
+ }
+ user->append(cptr, len - tics);
+ len= grantee->length() - len - 1 - tics;
+ host->length(0);
+
+ /*
+ String ' from strings.
+ */
+ cptr= ptr + 1;
+ tics= 0;
+ if (strncmp(cptr, "'", 1) == 0)
+ {
+ cptr++;
+ len--;
+ }
+ if (strncmp(cptr+len-1, "'", 1) == 0)
+ tics++;
+ host->append(cptr, len - tics);
+ return 0;
+}
+
+/*
+ Returns TRUE if user is defined on the system.
+*/
+bool user_exists(THD *thd, const String *grantee)
+{
+ String user;
+ String host;
+ bool user_exists= FALSE;
+
+ user.length(0);
+ host.length(0);
+ if (grantee)
+ {
+#ifndef EMBEDDED_LIBRARY
+ split_user_host((String *)grantee, &user, &host);
+ if (!user.ptr())
+ user.append("''");
+ user_exists= is_acl_user(host.ptr(), user.ptr());
+#else
+ user_exists= TRUE;
+#endif
+ }
+ return user_exists;
+}
+
/**
Locate the row in the information_schema view for this tablespace.
=== modified file 'sql/si_objects.h'
--- a/sql/si_objects.h 2008-07-05 08:41:26 +0000
+++ b/sql/si_objects.h 2008-08-20 13:23:10 +0000
@@ -115,6 +115,12 @@ private:
friend Obj *materialize_tablespace(const String *,
uint,
const String *);
+
+ friend Obj *materialize_db_grant(const String *,
+ const String *,
+ uint,
+ const String *);
+
};
@@ -222,6 +228,39 @@ public:
};
+/**
+ GrantObjIternator is an encapsulation of the three iterators for each level
+ of grant supported: database-, table- and routine-, and column-level.
+*/
+class GrantObjIterator : public ObjIterator
+{
+public:
+ GrantObjIterator(THD *thd, const String *db_name);
+
+ ~GrantObjIterator()
+ {
+ delete db_grants;
+ delete tbl_grants;
+ delete col_grants;
+ }
+
+ /**
+ This operation returns a pointer to the next object in an enumeration.
+ It returns NULL if there is no more objects.
+
+ The client is responsible to destroy the returned object.
+
+ @return a pointer to the object
+ @retval NULL if there is no more objects in an enumeration.
+ */
+ Obj *next();
+
+private:
+ ObjIterator *db_grants; ///< database-level grants
+ ObjIterator *tbl_grants; ///< table- and routine-level grants
+ ObjIterator *col_grants; ///< column-level grants
+};
+
///////////////////////////////////////////////////////////////////////////
// The functions in this section are intended to construct an instance of
@@ -429,6 +468,14 @@ ObjIterator *get_db_stored_functions(THD
ObjIterator *get_db_events(THD *thd, const String *db_name);
+/*
+ Creates a high-level iterator that iterates over database-, table-,
+ routine-, and column-level privileges which shall permit a single
+ iterator from the si_objects to retrieve all of the privileges for
+ a given database.
+*/
+ObjIterator *get_all_db_grants(THD *thd, const String *db_name);
+
///////////////////////////////////////////////////////////////////////////
// The functions are intended to enumerate dependent objects.
@@ -506,6 +553,11 @@ Obj *materialize_tablespace(const String
uint serialization_version,
const String *serialialization);
+Obj *materialize_db_grant(const String *grantee,
+ const String *db_name,
+ uint serialization_version,
+ const String *serialization);
+
///////////////////////////////////////////////////////////////////////////
bool is_internal_db_name(const String *db_name);
@@ -522,6 +574,11 @@ bool is_internal_db_name(const String *d
bool check_db_existence(const String *db_name);
/*
+ Returns TRUE if user is defined on the system.
+*/
+bool user_exists(THD *thd, const String *grantee);
+
+/*
This method returns a @c TablespaceObj object if the table has a tablespace.
*/
Obj *get_tablespace_for_table(THD *thd,
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2008-09-05 13:39:08 +0000
+++ b/sql/sql_class.cc 2008-09-10 12:50:02 +0000
@@ -537,6 +537,7 @@ THD::THD()
when the DDL blocker is engaged.
*/
DDL_exception(FALSE),
+ backup_wait_timeout(50),
#if defined(ENABLED_DEBUG_SYNC)
debug_sync_control(0),
#endif /* defined(ENABLED_DEBUG_SYNC) */
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2008-09-05 13:39:08 +0000
+++ b/sql/sql_class.h 2008-09-10 12:50:02 +0000
@@ -1936,6 +1936,7 @@ public:
when the DDL blocker is engaged.
*/
my_bool DDL_exception; // Allow some DDL if there is an exception
+ ulong backup_wait_timeout;
Locked_tables_list locked_tables_list;
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2008-09-10 10:40:14 +0000
+++ b/sql/sql_parse.cc 2008-09-10 12:50:02 +0000
@@ -2484,7 +2484,11 @@ mysql_execute_command(THD *thd)
TABLE in the same way. That way we avoid that a new table is
created during a gobal read lock.
*/
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ {
+ res= 1;
+ goto ddl_blocker_err;
+ }
if (!thd->locked_tables_mode &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
{
@@ -2610,6 +2614,7 @@ mysql_execute_command(THD *thd)
/* put tables back for PS rexecuting */
end_with_restore_list:
DDL_blocker->end_DDL();
+ddl_blocker_err:
lex->link_first_table_back(create_table, link_to_local);
break;
}
@@ -2625,7 +2630,8 @@ end_with_restore_list:
table without having to do a full rebuild.
*/
{
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
/* Prepare stack copies to be re-execution safe */
HA_CREATE_INFO create_info;
Alter_info alter_info(lex->alter_info, thd->mem_root);
@@ -2693,7 +2699,8 @@ end_with_restore_list:
case SQLCOM_ALTER_TABLE:
{
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
ulong priv=0;
ulong priv_needed= ALTER_ACL;
@@ -2805,7 +2812,8 @@ end_with_restore_list:
goto error;
}
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
if (mysql_rename_tables(thd, first_table, 0))
{
DDL_blocker->end_DDL();
@@ -2905,7 +2913,8 @@ end_with_restore_list:
if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, FALSE, FALSE, UINT_MAX))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
res= mysql_repair_table(thd, first_table, &lex->check_opt);
DDL_blocker->end_DDL();
/* ! we write after unlocking the table */
@@ -2957,7 +2966,8 @@ end_with_restore_list:
if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, FALSE, FALSE, UINT_MAX))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
mysql_recreate_table(thd, first_table) :
mysql_optimize_table(thd, first_table, &lex->check_opt);
@@ -3198,7 +3208,8 @@ end_with_restore_list:
goto error;
}
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
res= mysql_truncate(thd, first_table, 0);
DDL_blocker->end_DDL();
@@ -3301,7 +3312,8 @@ end_with_restore_list:
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
thd->options|= OPTION_KEEP_LOG;
}
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
/* DDL and binlog write order protected by LOCK_open */
res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
lex->drop_temporary);
@@ -3547,7 +3559,8 @@ end_with_restore_list:
if (check_access(thd,CREATE_ACL,lex->name.str, 0, 1, 0,
is_schema_db(lex->name.str)))
break;
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
lex->name.str), &create_info, 0);
DDL_blocker->end_DDL();
@@ -3585,7 +3598,8 @@ end_with_restore_list:
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
goto error;
}
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
DDL_blocker->end_DDL();
break;
@@ -3623,7 +3637,8 @@ end_with_restore_list:
goto error;
}
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
res= mysql_upgrade_db(thd, db);
DDL_blocker->end_DDL();
if (!res)
@@ -3663,7 +3678,8 @@ end_with_restore_list:
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
goto error;
}
- DDL_blocker->check_DDL_blocker(thd);
+ if (!DDL_blocker->check_DDL_blocker(thd))
+ goto error;
res= mysql_alter_db(thd, db->str, &create_info);
DDL_blocker->end_DDL();
break;
| Thread |
|---|
| • bzr commit into mysql-6.0 branch (kgeorge:2828) | Georgi Kodinov | 10 Sep |