Below is the list of changes that have just been committed into a local
6.0 repository of rafal. When rafal does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-02-13 12:40:39+01:00, rafal@quant.(none) +11 -0
WL#4239 (Online Backup: extend kernel to handle all database objects)
This patch extends kernel so that it can handle the following types of objects:
- databases
- tables
- views
- stored routines
- events
- triggers
Note: dependencies are not handled.
mysql-test/r/backup_no_data.result@stripped, 2008-02-13 12:40:23+01:00, rafal@quant.(none) +2 -6
- result update
mysql-test/r/backup_objects.result@stripped, 2008-02-13 12:40:24+01:00, rafal@quant.(none) +293 -0
Results for backup_objects test.
mysql-test/r/backup_objects.result@stripped, 2008-02-13 12:40:24+01:00, rafal@quant.(none) +0 -0
mysql-test/t/backup_no_data.test@stripped, 2008-02-13 12:40:23+01:00, rafal@quant.(none) +6 -16
Don't use views in the test - they are not ignored any more.
mysql-test/t/backup_objects.test@stripped, 2008-02-13 12:40:24+01:00, rafal@quant.(none) +171 -0
Simple test for backing up various types of objects.
mysql-test/t/backup_objects.test@stripped, 2008-02-13 12:40:24+01:00, rafal@quant.(none) +0 -0
sql/backup/CMakeLists.txt@stripped, 2008-02-13 12:40:24+01:00, rafal@quant.(none) +1 -1
Remove meta_data.cc file.
sql/backup/catalog.cc@stripped, 2008-02-13 12:40:24+01:00, rafal@quant.(none) +140 -2
Add support for new object types.
sql/backup/catalog.h@stripped, 2008-02-13 12:40:24+01:00, rafal@quant.(none) +114 -19
Add support for new object types:
- new class PerDb_item for storing other objects
- new iterator PerDb_iterator
- modify Ditem_iterator to list not only tables but all the other objects belonging
to a database
- added m_items member to Image_info for storing list of all per-db objects
- added methods for inserting new object types into catalogue
- modify Db_iterator class so that new classes can be inherited from it
sql/backup/kernel.cc@stripped, 2008-02-13 12:40:24+01:00, rafal@quant.(none) +79 -12
- modify Backup_info::add_db_items() to add all objects belonging to a given database,
not only tables
- modify bcat_add_item() finction to handle new object types
sql/backup/stream_v1.c@stripped, 2008-02-13 12:40:24+01:00, rafal@quant.(none) +12 -2
Add new object types.
sql/backup/stream_v1.h@stripped, 2008-02-13 12:40:24+01:00, rafal@quant.(none) +4 -0
Add new object types.
sql/si_objects.cc@stripped, 2008-02-13 12:40:23+01:00, rafal@quant.(none) +3 -1
Fixes.
diff -Nrup a/mysql-test/r/backup_no_data.result b/mysql-test/r/backup_no_data.result
--- a/mysql-test/r/backup_no_data.result 2007-12-20 21:32:15 +01:00
+++ b/mysql-test/r/backup_no_data.result 2008-02-13 12:40:23 +01:00
@@ -50,17 +50,12 @@ other_db
test
SHOW TABLES IN empty_db;
Tables_in_empty_db
-USE other_db;
+USE empty_db;
DROP TABLE IF EXISTS t1;
-Warnings:
-Note 1051 Unknown table 't1'
CREATE TABLE t1 (
`dir_code` char(4),
`building` char(6)
) ENGINE=MYISAM DEFAULT CHARSET=latin1;
-USE empty_db;
-DROP VIEW IF EXISTS v1;
-CREATE VIEW v1 AS SELECT * FROM other_db.t1;
BACKUP DATABASE empty_db TO 'empty_db.bak';
backup_id
#
@@ -77,5 +72,6 @@ backup_id
USE empty_db;
SHOW TABLES;
Tables_in_empty_db
+t1
DROP DATABASE IF EXISTS empty_db;
DROP DATABASE IF EXISTS other_db;
diff -Nrup a/mysql-test/r/backup_objects.result b/mysql-test/r/backup_objects.result
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/r/backup_objects.result 2008-02-13 12:40:24 +01:00
@@ -0,0 +1,293 @@
+
+Starting Test - Backup
+
+Setting SQL_MODE = PIPES_AS_CONCAT
+SET SQL_MODE = 'PIPES_AS_CONCAT';
+Change client connection charset
+SET character_set_client = 'latin2';
+DROP DATABASE IF EXISTS bup_objects;
+CREATE DATABASE bup_objects;
+con1: Creating table
+CREATE TABLE bup_objects.t1 (col_a int, col_b CHAR(40)) ENGINE=INNODB;
+CREATE TABLE bup_objects.t2 (col_a int, col_b CHAR(40)) ENGINE=INNODB;
+con1: Loading data
+INSERT INTO bup_objects.t1 VALUES (01, "101 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (02, "102 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (03, "103 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (04, "201 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (05, "202 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (06, "203 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (07, "301 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (08, "302 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (09, "303 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (10, "401 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (11, "402 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (12, "403 Some data to test");
+INSERT INTO bup_objects.t2 VALUES (01, "101 Some data to test");
+INSERT INTO bup_objects.t2 VALUES (02, "102 Some data to test");
+INSERT INTO bup_objects.t2 VALUES (03, "103 Some data to test");
+CREATE VIEW bup_objects.v1 AS SELECT * FROM bup_objects.t1 WHERE col_a < 5;
+CREATE VIEW bup_objects.v2 AS SELECT * FROM bup_objects.t1 WHERE col_a >= 5;
+CREATE TRIGGER bup_objects.ins_t1 AFTER INSERT ON bup_objects.t1 FOR EACH ROW
+BEGIN
+DELETE FROM bup_objects.t2 WHERE col_a > 1;
+END;
+||
+CREATE EVENT bup_objects.e1 ON SCHEDULE EVERY 1 YEAR DO
+DELETE FROM bup_objects.t2 WHERE col_a > 100;
+||
+CREATE PROCEDURE bup_objects.p1()
+BEGIN
+UPDATE bup_objects.t1 SET col_b = "Procedure p1 was here." WHERE col_a < 3;
+END;
+||
+CREATE FUNCTION bup_objects.f1() RETURNS INTEGER
+BEGIN
+DECLARE v_out INT;
+SELECT count(*) FROM bup_objects.t1 INTO v_out;
+RETURN v_out;
+END;
+||
+Using the objects.
+INSERT INTO bup_objects.t1 VALUES (30, "a new row.");
+CALL bup_objects.p1();
+SELECT bup_objects.f1();
+bup_objects.f1()
+13
+Showing objects and create statements.
+SHOW CREATE DATABASE bup_objects;;
+Database bup_objects
+Create Database CREATE DATABASE `bup_objects` /*!40100 DEFAULT CHARACTER SET latin1 */
+SHOW CREATE TABLE bup_objects.t1;;
+Table t1
+Create Table CREATE TABLE `t1` (
+ `col_a` int(11) DEFAULT NULL,
+ `col_b` char(40) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SHOW CREATE TABLE bup_objects.t2;;
+Table t2
+Create Table CREATE TABLE `t2` (
+ `col_a` int(11) DEFAULT NULL,
+ `col_b` char(40) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SHOW CREATE VIEW bup_objects.v1;;
+View v1
+Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `bup_objects`.`v1` AS select `bup_objects`.`t1`.`col_a` AS `col_a`,`bup_objects`.`t1`.`col_b` AS `col_b` from `bup_objects`.`t1` where (`bup_objects`.`t1`.`col_a` < 5)
+character_set_client latin2
+collation_connection latin1_swedish_ci
+SHOW CREATE VIEW bup_objects.v2;;
+View v2
+Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `bup_objects`.`v2` AS select `bup_objects`.`t1`.`col_a` AS `col_a`,`bup_objects`.`t1`.`col_b` AS `col_b` from `bup_objects`.`t1` where (`bup_objects`.`t1`.`col_a` >= 5)
+character_set_client latin2
+collation_connection latin1_swedish_ci
+SHOW CREATE PROCEDURE bup_objects.p1;;
+Procedure p1
+sql_mode PIPES_AS_CONCAT
+Create Procedure CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
+BEGIN
+UPDATE bup_objects.t1 SET col_b = "Procedure p1 was here." WHERE col_a < 3;
+END
+character_set_client latin2
+collation_connection latin1_swedish_ci
+Database Collation latin1_swedish_ci
+SHOW CREATE FUNCTION bup_objects.f1;;
+Function f1
+sql_mode PIPES_AS_CONCAT
+Create Function CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
+BEGIN
+DECLARE v_out INT;
+SELECT count(*) FROM bup_objects.t1 INTO v_out;
+RETURN v_out;
+END
+character_set_client latin2
+collation_connection latin1_swedish_ci
+Database Collation latin1_swedish_ci
+SHOW CREATE TRIGGER bup_objects.ins_t1;;
+Trigger ins_t1
+sql_mode PIPES_AS_CONCAT
+SQL Original Statement CREATE DEFINER=`root`@`localhost` TRIGGER bup_objects.ins_t1 AFTER INSERT ON bup_objects.t1 FOR EACH ROW
+BEGIN
+DELETE FROM bup_objects.t2 WHERE col_a > 1;
+END
+character_set_client latin2
+collation_connection latin1_swedish_ci
+Database Collation latin1_swedish_ci
+SELECT * FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'bup_objects' AND event_name = 'e1';;
+EVENT_CATALOG NULL
+EVENT_SCHEMA bup_objects
+EVENT_NAME e1
+DEFINER root@localhost
+TIME_ZONE SYSTEM
+EVENT_BODY SQL
+EVENT_DEFINITION DELETE FROM bup_objects.t2 WHERE col_a > 100
+EVENT_TYPE RECURRING
+EXECUTE_AT NULL
+INTERVAL_VALUE 1
+INTERVAL_FIELD YEAR
+SQL_MODE PIPES_AS_CONCAT
+STARTS #
+ENDS #
+STATUS ENABLED
+ON_COMPLETION NOT PRESERVE
+CREATED #
+LAST_ALTERED #
+LAST_EXECUTED #
+EVENT_COMMENT
+ORIGINATOR 1
+CHARACTER_SET_CLIENT latin2
+COLLATION_CONNECTION latin1_swedish_ci
+DATABASE_COLLATION latin1_swedish_ci
+SELECT table_name FROM INFORMATION_SCHEMA.TABLES
+WHERE table_schema = 'bup_objects';
+table_name
+t1
+t2
+v1
+v2
+SELECT table_name as view_name FROM INFORMATION_SCHEMA.VIEWS
+WHERE table_schema = 'bup_objects';
+view_name
+v1
+v2
+SELECT routine_name as proc_name FROM INFORMATION_SCHEMA.ROUTINES
+WHERE routine_schema = 'bup_objects' AND routine_type = 'PROCEDURE';
+proc_name
+p1
+SELECT routine_name as func_name FROM INFORMATION_SCHEMA.ROUTINES
+WHERE routine_schema = 'bup_objects' AND routine_type = 'FUNCTION';
+func_name
+f1
+SELECT trigger_name, event_manipulation, event_object_table
+FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'bup_objects';
+trigger_name event_manipulation event_object_table
+ins_t1 INSERT t1
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS
+WHERE event_schema = 'bup_objects';
+event_name
+e1
+Backup data.
+BACKUP DATABASE bup_objects TO 'bup_objects.bak';
+backup_id
+#
+Dropping database.
+DROP DATABASE bup_objects;
+Setting SQL_MODE = ''
+SET SQL_MODE = '';
+Change client connection charset
+SET character_set_client = 'latin1';
+RESTORE FROM 'bup_objects.bak';
+backup_id
+#
+Showing objects and create statements.
+SHOW CREATE DATABASE bup_objects;;
+Database bup_objects
+Create Database CREATE DATABASE `bup_objects` /*!40100 DEFAULT CHARACTER SET latin1 */
+SHOW CREATE TABLE bup_objects.t1;;
+Table t1
+Create Table CREATE TABLE `t1` (
+ `col_a` int(11) DEFAULT NULL,
+ `col_b` char(40) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SHOW CREATE TABLE bup_objects.t2;;
+Table t2
+Create Table CREATE TABLE `t2` (
+ `col_a` int(11) DEFAULT NULL,
+ `col_b` char(40) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SHOW CREATE VIEW bup_objects.v1;;
+View v1
+Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`col_a` AS `col_a`,`t1`.`col_b` AS `col_b` from `t1` where (`t1`.`col_a` < 5)
+character_set_client latin1
+collation_connection latin1_swedish_ci
+SHOW CREATE VIEW bup_objects.v2;;
+View v2
+Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t1`.`col_a` AS `col_a`,`t1`.`col_b` AS `col_b` from `t1` where (`t1`.`col_a` >= 5)
+character_set_client latin1
+collation_connection latin1_swedish_ci
+SHOW CREATE PROCEDURE bup_objects.p1;;
+Procedure p1
+sql_mode PIPES_AS_CONCAT
+Create Procedure CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
+BEGIN
+UPDATE bup_objects.t1 SET col_b = "Procedure p1 was here." WHERE col_a < 3;
+END
+character_set_client latin2
+collation_connection latin1_swedish_ci
+Database Collation latin1_swedish_ci
+SHOW CREATE FUNCTION bup_objects.f1;;
+Function f1
+sql_mode PIPES_AS_CONCAT
+Create Function CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
+BEGIN
+DECLARE v_out INT;
+SELECT count(*) FROM bup_objects.t1 INTO v_out;
+RETURN v_out;
+END
+character_set_client latin2
+collation_connection latin1_swedish_ci
+Database Collation latin1_swedish_ci
+SHOW CREATE TRIGGER bup_objects.ins_t1;;
+Trigger ins_t1
+sql_mode PIPES_AS_CONCAT
+SQL Original Statement CREATE DEFINER=`root`@`localhost` TRIGGER bup_objects.ins_t1 AFTER INSERT ON bup_objects.t1 FOR EACH ROW
+BEGIN
+DELETE FROM bup_objects.t2 WHERE col_a > 1;
+END
+character_set_client latin2
+collation_connection latin1_swedish_ci
+Database Collation latin1_swedish_ci
+SELECT * FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'bup_objects' AND event_name = 'e1';;
+EVENT_CATALOG NULL
+EVENT_SCHEMA bup_objects
+EVENT_NAME e1
+DEFINER root@localhost
+TIME_ZONE SYSTEM
+EVENT_BODY SQL
+EVENT_DEFINITION DELETE FROM bup_objects.t2 WHERE col_a > 100
+EVENT_TYPE RECURRING
+EXECUTE_AT NULL
+INTERVAL_VALUE 1
+INTERVAL_FIELD YEAR
+SQL_MODE PIPES_AS_CONCAT
+STARTS #
+ENDS #
+STATUS ENABLED
+ON_COMPLETION NOT PRESERVE
+CREATED #
+LAST_ALTERED #
+LAST_EXECUTED #
+EVENT_COMMENT
+ORIGINATOR 1
+CHARACTER_SET_CLIENT latin2
+COLLATION_CONNECTION latin1_swedish_ci
+DATABASE_COLLATION latin1_swedish_ci
+SELECT table_name FROM INFORMATION_SCHEMA.TABLES
+WHERE table_schema = 'bup_objects';
+table_name
+t1
+t2
+v1
+v2
+SELECT table_name as view_name FROM INFORMATION_SCHEMA.VIEWS
+WHERE table_schema = 'bup_objects';
+view_name
+v1
+v2
+SELECT routine_name as proc_name FROM INFORMATION_SCHEMA.ROUTINES
+WHERE routine_schema = 'bup_objects' AND routine_type = 'PROCEDURE';
+proc_name
+p1
+SELECT routine_name as func_name FROM INFORMATION_SCHEMA.ROUTINES
+WHERE routine_schema = 'bup_objects' AND routine_type = 'FUNCTION';
+func_name
+f1
+SELECT trigger_name, event_manipulation, event_object_table
+FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'bup_objects';
+trigger_name event_manipulation event_object_table
+ins_t1 INSERT t1
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS
+WHERE event_schema = 'bup_objects';
+event_name
+e1
+Cleanup
+DROP DATABASE bup_objects;
diff -Nrup a/mysql-test/t/backup_no_data.test b/mysql-test/t/backup_no_data.test
--- a/mysql-test/t/backup_no_data.test 2007-12-20 21:32:16 +01:00
+++ b/mysql-test/t/backup_no_data.test 2008-02-13 12:40:23 +01:00
@@ -1,10 +1,5 @@
--source include/not_embedded.inc
-connect (backup,localhost,root,,);
-
-connection backup;
-
-
--disable_warnings
DROP DATABASE IF EXISTS empty_db;
DROP DATABASE IF EXISTS other_db;
@@ -48,25 +43,17 @@ RESTORE FROM 'all.bak';
SHOW DATABASES;
SHOW TABLES IN empty_db;
-connection backup;
-
-USE other_db;
+USE empty_db;
+--disable_warnings
DROP TABLE IF EXISTS t1;
+--enable_warnings
CREATE TABLE t1 (
`dir_code` char(4),
`building` char(6)
) ENGINE=MYISAM DEFAULT CHARSET=latin1;
-USE empty_db;
-
---disable_warnings
-DROP VIEW IF EXISTS v1;
---enable_warnings
-
-CREATE VIEW v1 AS SELECT * FROM other_db.t1;
-
--error 0,1
--remove_file $MYSQLTEST_VARDIR/master-data/empty_db.bak
--replace_column 1 #
@@ -80,8 +67,11 @@ RESTORE FROM 'empty_db.bak';
USE empty_db;
SHOW TABLES;
+
+--disable_warnings
DROP DATABASE IF EXISTS empty_db;
DROP DATABASE IF EXISTS other_db;
+--enable_warnings
--error 0,1
--remove_file $MYSQLTEST_VARDIR/master-data/all.bak
diff -Nrup a/mysql-test/t/backup_objects.test b/mysql-test/t/backup_objects.test
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/backup_objects.test 2008-02-13 12:40:24 +01:00
@@ -0,0 +1,171 @@
+#
+# This test testing backup and restore for database objects.
+#
+
+--source include/have_innodb.inc
+--source include/not_embedded.inc
+
+connect (con1,localhost,root,,);
+connection con1;
+
+##############################################################
+--echo
+--echo Starting Test - Backup
+--echo
+##############################################################
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_objects.bak
+
+# Set SQL_MODE and client charset
+--echo Setting SQL_MODE = PIPES_AS_CONCAT
+SET SQL_MODE = 'PIPES_AS_CONCAT';
+
+--echo Change client connection charset
+SET character_set_client = 'latin2';
+
+# Create database and objects for this test and tailor it to the test.
+--disable_warnings
+DROP DATABASE IF EXISTS bup_objects;
+--enable_warnings
+
+CREATE DATABASE bup_objects;
+
+# Create table and load it with data.
+--echo con1: Creating table
+CREATE TABLE bup_objects.t1 (col_a int, col_b CHAR(40)) ENGINE=INNODB;
+CREATE TABLE bup_objects.t2 (col_a int, col_b CHAR(40)) ENGINE=INNODB;
+
+--echo con1: Loading data
+INSERT INTO bup_objects.t1 VALUES (01, "101 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (02, "102 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (03, "103 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (04, "201 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (05, "202 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (06, "203 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (07, "301 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (08, "302 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (09, "303 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (10, "401 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (11, "402 Some data to test");
+INSERT INTO bup_objects.t1 VALUES (12, "403 Some data to test");
+
+INSERT INTO bup_objects.t2 VALUES (01, "101 Some data to test");
+INSERT INTO bup_objects.t2 VALUES (02, "102 Some data to test");
+INSERT INTO bup_objects.t2 VALUES (03, "103 Some data to test");
+
+# Create views of the table.
+CREATE VIEW bup_objects.v1 AS SELECT * FROM bup_objects.t1 WHERE col_a < 5;
+CREATE VIEW bup_objects.v2 AS SELECT * FROM bup_objects.t1 WHERE col_a >= 5;
+
+# Create trigger for table.
+delimiter ||;
+CREATE TRIGGER bup_objects.ins_t1 AFTER INSERT ON bup_objects.t1 FOR EACH ROW
+BEGIN
+ DELETE FROM bup_objects.t2 WHERE col_a > 1;
+END;
+||
+
+# Create event.
+CREATE EVENT bup_objects.e1 ON SCHEDULE EVERY 1 YEAR DO
+ DELETE FROM bup_objects.t2 WHERE col_a > 100;
+||
+
+# Create procedure.
+CREATE PROCEDURE bup_objects.p1()
+BEGIN
+ UPDATE bup_objects.t1 SET col_b = "Procedure p1 was here." WHERE col_a < 3;
+END;
+||
+
+# Create function.
+CREATE FUNCTION bup_objects.f1() RETURNS INTEGER
+BEGIN
+ DECLARE v_out INT;
+ SELECT count(*) FROM bup_objects.t1 INTO v_out;
+ RETURN v_out;
+END;
+||
+
+delimiter ;||
+
+# Exercise the objects.
+--echo Using the objects.
+INSERT INTO bup_objects.t1 VALUES (30, "a new row.");
+CALL bup_objects.p1();
+SELECT bup_objects.f1();
+
+# Show the data and CREATE statements
+--echo Showing objects and create statements.
+--query_vertical SHOW CREATE DATABASE bup_objects;
+--query_vertical SHOW CREATE TABLE bup_objects.t1;
+--query_vertical SHOW CREATE TABLE bup_objects.t2;
+--query_vertical SHOW CREATE VIEW bup_objects.v1;
+--query_vertical SHOW CREATE VIEW bup_objects.v2;
+--query_vertical SHOW CREATE PROCEDURE bup_objects.p1;
+--query_vertical SHOW CREATE FUNCTION bup_objects.f1;
+--query_vertical SHOW CREATE TRIGGER bup_objects.ins_t1;
+--replace_column 13 # 14 # 17 # 18 # 19 #
+--query_vertical SELECT * FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'bup_objects' AND event_name = 'e1';
+
+SELECT table_name FROM INFORMATION_SCHEMA.TABLES
+ WHERE table_schema = 'bup_objects';
+SELECT table_name as view_name FROM INFORMATION_SCHEMA.VIEWS
+ WHERE table_schema = 'bup_objects';
+SELECT routine_name as proc_name FROM INFORMATION_SCHEMA.ROUTINES
+ WHERE routine_schema = 'bup_objects' AND routine_type = 'PROCEDURE';
+SELECT routine_name as func_name FROM INFORMATION_SCHEMA.ROUTINES
+ WHERE routine_schema = 'bup_objects' AND routine_type = 'FUNCTION';
+SELECT trigger_name, event_manipulation, event_object_table
+ FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'bup_objects';
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS
+ WHERE event_schema = 'bup_objects';
+
+# Backup and restore the data.
+--echo Backup data.
+--replace_column 1 #
+BACKUP DATABASE bup_objects TO 'bup_objects.bak';
+
+--echo Dropping database.
+DROP DATABASE bup_objects;
+
+# Set SQL_MODE and client charset
+--echo Setting SQL_MODE = ''
+SET SQL_MODE = '';
+
+--echo Change client connection charset
+SET character_set_client = 'latin1';
+
+--replace_column 1 #
+RESTORE FROM 'bup_objects.bak';
+
+# Show the data and CREATE statements
+--echo Showing objects and create statements.
+--query_vertical SHOW CREATE DATABASE bup_objects;
+--query_vertical SHOW CREATE TABLE bup_objects.t1;
+--query_vertical SHOW CREATE TABLE bup_objects.t2;
+--query_vertical SHOW CREATE VIEW bup_objects.v1;
+--query_vertical SHOW CREATE VIEW bup_objects.v2;
+--query_vertical SHOW CREATE PROCEDURE bup_objects.p1;
+--query_vertical SHOW CREATE FUNCTION bup_objects.f1;
+--query_vertical SHOW CREATE TRIGGER bup_objects.ins_t1;
+--replace_column 13 # 14 # 17 # 18 # 19 #
+--query_vertical SELECT * FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'bup_objects' AND event_name = 'e1';
+
+SELECT table_name FROM INFORMATION_SCHEMA.TABLES
+ WHERE table_schema = 'bup_objects';
+SELECT table_name as view_name FROM INFORMATION_SCHEMA.VIEWS
+ WHERE table_schema = 'bup_objects';
+SELECT routine_name as proc_name FROM INFORMATION_SCHEMA.ROUTINES
+ WHERE routine_schema = 'bup_objects' AND routine_type = 'PROCEDURE';
+SELECT routine_name as func_name FROM INFORMATION_SCHEMA.ROUTINES
+ WHERE routine_schema = 'bup_objects' AND routine_type = 'FUNCTION';
+SELECT trigger_name, event_manipulation, event_object_table
+ FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'bup_objects';
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS
+ WHERE event_schema = 'bup_objects';
+
+--echo Cleanup
+DROP DATABASE bup_objects;
+
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_objects.bak
diff -Nrup a/sql/backup/CMakeLists.txt b/sql/backup/CMakeLists.txt
--- a/sql/backup/CMakeLists.txt 2008-01-14 20:49:08 +01:00
+++ b/sql/backup/CMakeLists.txt 2008-02-13 12:40:24 +01:00
@@ -23,7 +23,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/
${CMAKE_SOURCE_DIR}/extra/yassl/include)
SET(BACKUP_SOURCES stream.cc logger.cc kernel.cc
- catalog.cc meta_data.cc data_backup.cc
+ catalog.cc data_backup.cc
be_default.cc buffer_iterator.cc
be_snapshot.cc be_thread.cc backup_progress.cc
backup_test.cc)
diff -Nrup a/sql/backup/catalog.cc b/sql/backup/catalog.cc
--- a/sql/backup/catalog.cc 2008-01-15 01:26:32 +01:00
+++ b/sql/backup/catalog.cc 2008-02-13 12:40:24 +01:00
@@ -21,7 +21,7 @@ namespace backup {
/* Image_info implementation */
Image_info::Image_info():
- backup_prog_id(0), table_count(0), data_size(0)
+ backup_prog_id(0), table_count(0), data_size(0), m_items(32,128)
{
/* initialize st_bstream_image_header members */
version= 1;
@@ -88,6 +88,14 @@ Image_info::~Image_info()
if (db)
delete db->obj_ptr();
}
+
+ for (uint i=0; i < m_items.size(); ++i)
+ {
+ PerDb_item *it= m_items[i];
+
+ if (it)
+ delete it->obj_ptr();
+ }
}
@@ -156,12 +164,139 @@ Image_info::locate_item(const st_bstream
return get_table(ti->snap_no,item->pos);
}
+ case BSTREAM_IT_VIEW:
+ case BSTREAM_IT_SPROC:
+ case BSTREAM_IT_SFUNC:
+ case BSTREAM_IT_EVENT:
+ case BSTREAM_IT_TRIGGER:
+ return get_db_object(item->pos);
+
default:
// TODO: warn or report error
return NULL;
}
}
+/**
+ Store in Backup_image all objects enumerated by the iterator.
+ */
+int Image_info::add_objects(Db_item &dbi,
+ const enum_bstream_item_type type,
+ obs::ObjIterator &it)
+{
+ using namespace obs;
+
+ Obj *obj;
+
+ while ((obj= it.next()))
+ if (!add_db_object(dbi, type, *obj))
+ {
+ delete obj;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+Image_info::PerDb_item* Image_info::add_db_object(Db_item &dbi,
+ const enum_bstream_item_type type,
+ obs::Obj &obj)
+{
+ ulong pos= m_items.size();
+
+ PerDb_item *it= m_items.get_entry(pos);
+
+ if (!it)
+ return NULL;
+
+ *it= obj;
+ it->base.type= type;
+ it->base.pos= pos;
+ it->db= &dbi;
+
+ return it;
+}
+
+Image_info::PerDb_item* Image_info::add_db_object(Db_item &dbi,
+ const enum_bstream_item_type type,
+ const ::String &name)
+{
+ ulong pos= m_items.size();
+
+ PerDb_item *it= m_items.get_entry(pos);
+
+ if (!it)
+ return NULL;
+
+ *it= name;
+ it->base.type= type;
+ it->base.pos= pos;
+ it->db= &dbi;
+ it->m_db_name= dbi.name();
+
+ return it;
+}
+
+obs::Obj* Image_info::PerDb_item::obj_ptr(uint ver, ::String &sdata)
+{
+ using namespace obs;
+
+ Obj *obj;
+
+ switch (base.type) {
+ case BSTREAM_IT_VIEW:
+ obj= materialize_view(&m_db_name, &m_name, ver, &sdata); break;
+ case BSTREAM_IT_SPROC:
+ obj= materialize_stored_procedure(&m_db_name, &m_name, ver, &sdata); break;
+ case BSTREAM_IT_SFUNC:
+ obj= materialize_stored_function(&m_db_name, &m_name, ver, &sdata); break;
+ case BSTREAM_IT_EVENT:
+ obj= materialize_event(&m_db_name, &m_name, ver, &sdata); break;
+ case BSTREAM_IT_TRIGGER:
+ obj= materialize_trigger(&m_db_name, &m_name, ver, &sdata); break;
+ default: obj= NULL;
+ }
+
+ return obj;
+}
+
+bool Image_info::Ditem_iterator::next()
+{
+ if (ptr)
+ ptr= ptr->next_table;
+
+ if (ptr)
+ return TRUE;
+
+ bool more=TRUE;
+
+ // advance to next element in other list if we are inside it
+ if (other_list)
+ more= PerDb_iterator::next();
+
+ other_list= TRUE; // mark that we are now inside the other list
+
+ // return if there are no more elements in the other list
+ if (!more)
+ return FALSE;
+
+ // find an element belonging to our database
+ do
+ {
+ PerDb_item *it= (PerDb_item*)PerDb_iterator::get_ptr();
+
+ if (!it)
+ return FALSE;
+
+ if (it->m_db_name == db_name)
+ return TRUE;
+ }
+ while (PerDb_iterator::next());
+
+ // we haven't found any object belonging to our database
+ return FALSE;
+}
+
} // backup namespace
@@ -179,6 +314,9 @@ void* bcat_iterator_get(st_bstream_image
switch (type) {
case BSTREAM_IT_PERDB:
+ return
+ new backup::Image_info::PerDb_iterator(*static_cast<backup::Image_info*>(catalogue));
+
case BSTREAM_IT_PERTABLE:
return &null_iter;
@@ -281,7 +419,7 @@ void bcat_db_iterator_free(st_bstream_i
struct st_bstream_db_info *db,
void *iter)
{
- delete (backup::Image_info::Ditem_iterator*)iter;
+ delete (backup::Image_info::Iterator*)iter;
}
}
diff -Nrup a/sql/backup/catalog.h b/sql/backup/catalog.h
--- a/sql/backup/catalog.h 2008-01-15 01:26:32 +01:00
+++ b/sql/backup/catalog.h 2008-02-13 12:40:24 +01:00
@@ -44,10 +44,12 @@ class Image_info: public st_bstream_imag
class Item; ///< base class for all item types
class Db_item;
class Table_item;
+ class PerDb_item;
class Iterator; ///< base for all iterators
class Db_iterator; ///< iterates over databases in archive
- class Ditem_iterator; ///< iterates over per-db items
+ class Ditem_iterator; ///< iterates over all objects in a given database
+ class PerDb_iterator; ///< iterates over all per-db objects, except tables
virtual ~Image_info();
@@ -92,11 +94,11 @@ class Image_info: public st_bstream_imag
{
return add_db(db,count());
}
-
};
Databases m_db; ///< list of databases
Snapshot_info *m_snap[256]; ///< list of snapshots
+ Dynamic_array<PerDb_item> m_items;
Image_info();
@@ -136,6 +138,14 @@ class Image_info: public st_bstream_imag
Item* locate_item(const st_bstream_item_info*) const;
+ PerDb_item* add_db_object(Db_item&, const enum_bstream_item_type, obs::Obj&);
+ PerDb_item* add_db_object(Db_item&, const enum_bstream_item_type, const ::String&);
+
+ PerDb_item* get_db_object(ulong pos) const
+ { return m_items[pos]; }
+
+ int add_objects(Db_item&, const enum_bstream_item_type, obs::ObjIterator&);
+
private:
/**
@@ -429,7 +439,7 @@ class Image_info::Db_item
/// Store information about database @c db.
Db_item& operator=(const Db_ref &db)
{
- Image_info::Item::m_name= db.name(); // save name of the db
+ Image_info::Item::m_name.copy(db.name()); // save name of the db
/*
setup the name member (inherited from bstream_item_info) to point
at the db name
@@ -526,6 +536,69 @@ class Image_info::Table_item
int ::bcat_add_item(st_bstream_image_header*, struct st_bstream_item_info*);
};
+
+class Image_info::PerDb_item
+ : public st_bstream_dbitem_info,
+ public Image_info::Item,
+ public Obj_ref_base
+{
+ public:
+
+ String m_db_name;
+
+ PerDb_item():
+ Obj_ref_base(NULL)
+ {}
+
+ PerDb_item(String &db_name, String &name):
+ Obj_ref_base(NULL)
+ {
+ m_db_name.copy(db_name);
+ m_name.copy(name);
+ }
+
+ PerDb_item(obs::Obj *obj):
+ Obj_ref_base(obj)
+ {
+ m_db_name= *obj->get_db_name();
+ m_name= *obj->get_name();
+ }
+
+ obs::Obj *obj_ptr()
+ { return Obj_ref_base::obj_ptr(); }
+
+ obs::Obj* obj_ptr(uint, ::String&);
+
+ PerDb_item& operator= (obs::Obj &obj)
+ {
+ m_name= *obj.get_name();
+ m_db_name= *obj.get_db_name();
+ m_obj= &obj;
+
+ base.name.begin= (byte*) m_name.ptr();
+ base.name.end= base.name.begin + m_name.length();
+
+ // These should be set up externally
+ base.type= BSTREAM_IT_TABLE;
+ base.pos= 0;
+ db= NULL;
+
+ return *this;
+ }
+
+ PerDb_item& operator= (const ::String &name)
+ {
+ m_name.copy(name);
+
+ base.name.begin= (byte*) m_name.ptr();
+ base.name.end= base.name.begin + m_name.length();
+
+ return *this;
+ }
+
+ const st_bstream_item_info* info() const { return &base; }
+};
+
/**
Add table to given snapshot at the indicated location.
@@ -697,7 +770,7 @@ class Image_info::Iterator
class Image_info::Db_iterator
: public Image_info::Iterator
{
- uint pos;
+ ulong pos;
public:
@@ -707,50 +780,72 @@ class Image_info::Db_iterator
find_non_null_pos();
}
- private:
+ protected:
const Item* get_ptr() const
- { return m_info.m_db[pos]; }
+ { return get_ptr(pos); }
bool next()
{
pos++;
find_non_null_pos();
- return pos < m_info.m_db.count();
+ return pos < count();
}
void find_non_null_pos()
{
- for(; pos < m_info.m_db.count() && m_info.m_db[pos] == NULL; ++pos);
+ for(; pos < count() && get_ptr(pos) == NULL; ++pos);
}
+
+ virtual Item* get_ptr(ulong pos) const
+ { return m_info.m_db[pos]; }
+
+ virtual ulong count() const
+ { return m_info.m_db.count(); }
+
};
+class Image_info::PerDb_iterator: public Image_info::Db_iterator
+{
+ public:
+
+ PerDb_iterator(const Image_info &info): Db_iterator(info)
+ {}
+
+ protected:
+
+ const Item* get_ptr() const
+ { return Db_iterator::get_ptr(); } // FIXME
+
+ Item* get_ptr(ulong pos) const
+ { return m_info.m_items[pos]; }
+
+ ulong count() const
+ { return m_info.m_items.size(); }
+};
class Image_info::Ditem_iterator
- : public Image_info::Iterator
+ : public Image_info::PerDb_iterator
{
Table_item *ptr;
+ String db_name;
+ bool other_list;
public:
- Ditem_iterator(const Image_info &info, const Db_item &db): Iterator(info)
+ Ditem_iterator(const Image_info &info, const Db_item &db):
+ PerDb_iterator(info), other_list(FALSE)
{
ptr= db.m_tables;
+ db_name.copy(db.name());
}
private:
const Item* get_ptr() const
- { return ptr; }
-
- bool next()
- {
- if (ptr)
- ptr= ptr->next_table;
-
- return ptr != NULL;
- }
+ { return ptr ? ptr : PerDb_iterator::get_ptr(); }
+ bool next();
};
} // backup namespace
diff -Nrup a/sql/backup/kernel.cc b/sql/backup/kernel.cc
--- a/sql/backup/kernel.cc 2008-01-15 01:26:32 +01:00
+++ b/sql/backup/kernel.cc 2008-02-13 12:40:24 +01:00
@@ -838,19 +838,9 @@ int Backup_info::add_db_items(Db_item &d
int res= 0;
Obj *t= NULL;
-
-
+
while ((t= it->next()))
{
-/*
- if (engine.is_empty())
- {
- Table_ref::describe_buf buf;
- report_error(log_level::WARNING,ER_BACKUP_NO_ENGINE,t.describe(buf));
- delete name;
- continue;
- }
-*/
DBUG_PRINT("backup", ("Found table %s for database %s",
t->get_name()->ptr(), dbi.name().ptr()));
@@ -870,6 +860,61 @@ int Backup_info::add_db_items(Db_item &d
goto error;
}
+ delete it;
+ it= get_db_stored_procedures(m_thd, &dbi.name());
+
+ if (!it)
+ {
+ // TODO: report error
+ goto error;
+ }
+
+ add_objects(dbi, BSTREAM_IT_SPROC, *it);
+
+ delete it;
+ it= get_db_stored_functions(m_thd, &dbi.name());
+
+ if (!it)
+ {
+ // TODO: report error
+ goto error;
+ }
+
+ add_objects(dbi, BSTREAM_IT_SFUNC, *it);
+
+ delete it;
+ it= get_db_views(m_thd, &dbi.name());
+
+ if (!it)
+ {
+ // TODO: report error
+ goto error;
+ }
+
+ add_objects(dbi, BSTREAM_IT_VIEW, *it);
+
+ delete it;
+ it= get_db_events(m_thd, &dbi.name());
+
+ if (!it)
+ {
+ // TODO: report error
+ goto error;
+ }
+
+ add_objects(dbi, BSTREAM_IT_EVENT, *it);
+
+ delete it;
+ it= get_db_triggers(m_thd, &dbi.name());
+
+ if (!it)
+ {
+ // TODO: report error
+ goto error;
+ }
+
+ add_objects(dbi, BSTREAM_IT_TRIGGER, *it);
+
goto finish;
error:
@@ -883,7 +928,6 @@ int Backup_info::add_db_items(Db_item &d
return res;
}
-
/**
Add table to archive's list of meta-data items.
@@ -1303,6 +1347,29 @@ int bcat_add_item(st_bstream_image_heade
return BSTREAM_OK;
}
+
+ case BSTREAM_IT_VIEW:
+ case BSTREAM_IT_SPROC:
+ case BSTREAM_IT_SFUNC:
+ case BSTREAM_IT_EVENT:
+ case BSTREAM_IT_TRIGGER:
+ {
+ st_bstream_dbitem_info *it= (st_bstream_dbitem_info*)item;
+
+ DBUG_ASSERT(it->db);
+
+ Image_info::Db_item *db= (Image_info::Db_item*)
+ info->locate_item((st_bstream_item_info*)it->db);
+
+ DBUG_ASSERT(db);
+
+ Image_info::PerDb_item *it1= info->add_db_object(*db, item->type, name_str);
+
+ if (!it1)
+ return BSTREAM_ERROR;
+
+ return BSTREAM_OK;
+ }
default:
return BSTREAM_OK;
diff -Nrup a/sql/backup/stream_v1.c b/sql/backup/stream_v1.c
--- a/sql/backup/stream_v1.c 2007-12-03 21:28:16 +01:00
+++ b/sql/backup/stream_v1.c 2008-02-13 12:40:24 +01:00
@@ -834,6 +834,10 @@ int bstream_wr_item_type(backup_stream *
case BSTREAM_IT_DB: return bstream_wr_int2(s,4);
case BSTREAM_IT_TABLE: return bstream_wr_int2(s,5);
case BSTREAM_IT_VIEW: return bstream_wr_int2(s,6);
+ case BSTREAM_IT_SPROC: return bstream_wr_int2(s,7);
+ case BSTREAM_IT_SFUNC: return bstream_wr_int2(s,8);
+ case BSTREAM_IT_EVENT: return bstream_wr_int2(s,9);
+ case BSTREAM_IT_TRIGGER: return bstream_wr_int2(s,10);
case BSTREAM_IT_LAST: return bstream_wr_int2(s,0);
default: return BSTREAM_ERROR;
}
@@ -865,6 +869,10 @@ int bstream_rd_item_type(backup_stream *
case 4: *type= BSTREAM_IT_DB; break;
case 5: *type= BSTREAM_IT_TABLE; break;
case 6: *type= BSTREAM_IT_VIEW; break;
+ case 7: *type= BSTREAM_IT_SPROC; break;
+ case 8: *type= BSTREAM_IT_SFUNC; break;
+ case 9: *type= BSTREAM_IT_EVENT; break;
+ case 10: *type= BSTREAM_IT_TRIGGER; break;
default: return BSTREAM_ERROR;
}
@@ -891,10 +899,12 @@ int bstream_rd_item_type(backup_stream *
[optional item data] is used only for tables:
- [optional item data (table)]= [ flags:1 ! snapshot no:1 ! optional extra data ]
+ [optional item data (table)]= [ flags:1 ! snapshot no:1 ! pos !
+ optional extra data ]
@endverbatim
- [snapshot no] tells which snapshot contains tables data.
+ [snapshot no] tells which snapshot contains tables data and [pos] tells what
+ is the position of the table in this snapshot.
Presence of extra data is indicated by a flag.
@verbatim
diff -Nrup a/sql/backup/stream_v1.h b/sql/backup/stream_v1.h
--- a/sql/backup/stream_v1.h 2007-11-29 20:57:01 +01:00
+++ b/sql/backup/stream_v1.h 2008-02-13 12:40:24 +01:00
@@ -215,6 +215,10 @@ enum enum_bstream_item_type {
BSTREAM_IT_DB,
BSTREAM_IT_TABLE,
BSTREAM_IT_VIEW,
+ BSTREAM_IT_SPROC,
+ BSTREAM_IT_SFUNC,
+ BSTREAM_IT_EVENT,
+ BSTREAM_IT_TRIGGER,
BSTREAM_IT_LAST
};
diff -Nrup a/sql/si_objects.cc b/sql/si_objects.cc
--- a/sql/si_objects.cc 2008-01-15 01:10:55 +01:00
+++ b/sql/si_objects.cc 2008-02-13 12:40:23 +01:00
@@ -101,6 +101,8 @@ int silent_exec(THD *thd, String *query)
mysql_parse(thd, next_packet, length, & found_semicolon);
}
+ close_thread_tables(thd);
+
thd->net.vio= save_vio;
if (thd->is_error())
@@ -989,7 +991,7 @@ TableObj* DbTablesIterator::create_obj(T
t->field[1]->val_str(&db_name);
t->field[2]->val_str(&table_name);
t->field[3]->val_str(&type);
- t->field[5]->val_str(&engine);
+ t->field[4]->val_str(&engine);
// Skip tables not from the given database.