#At file:///localhome/jl208045/mysql/mergecaptain/mysql-6.0-backup-merge/
2729 Jorgen Loland 2008-11-28 [merge]
Merge mysql-6.0-backup -> mysql-6.0-backup-merge
modified:
mysql-test/suite/backup/r/backup.result
mysql-test/suite/backup/r/backup_errors.result
mysql-test/suite/backup/r/backup_views.result
mysql-test/suite/backup/t/backup.test
mysql-test/suite/backup/t/backup_errors.test
mysql-test/suite/backup/t/backup_myisam1.test
mysql-test/suite/backup/t/backup_views.test
sql/backup/backup_info.cc
sql/backup/backup_info.h
sql/backup/backup_kernel.h
sql/backup/data_backup.cc
sql/backup/image_info.cc
sql/backup/image_info.h
sql/backup/kernel.cc
sql/backup/logger.cc
sql/backup/logger.h
sql/backup/restore_info.h
sql/share/errmsg.txt
sql/si_logs.h
=== modified file 'mysql-test/suite/backup/r/backup.result'
--- a/mysql-test/suite/backup/r/backup.result 2008-11-17 09:57:51 +0000
+++ b/mysql-test/suite/backup/r/backup.result 2008-11-26 10:05:19 +0000
@@ -148,6 +148,35 @@ DROP DATABASE db1;
DROP DATABASE db2;
DROP DATABASE db3;
SET DEBUG_SYNC= 'RESET';
+CREATE DATABASE db1;
+BACKUP DATABASE db1 TO 'db1.bkp';
+backup_id
+#
+SELECT MAX(backup_id) FROM mysql.backup_history INTO @bid;
+SELECT validity_point_time FROM mysql.backup_history
+WHERE backup_id = @bid INTO @vp_time;
+SELECT binlog_file FROM mysql.backup_history
+WHERE backup_id = @bid INTO @vp_file;
+SELECT binlog_pos FROM mysql.backup_history
+WHERE backup_id = @bid INTO @vp_pos;
+DROP DATABASE db1;
+RESTORE FROM 'db1.bkp';
+backup_id
+#
+SELECT MAX(backup_id) FROM mysql.backup_history INTO @bid;
+SELECT validity_point_time = @vp_time FROM mysql.backup_history
+WHERE backup_id = @bid;
+validity_point_time = @vp_time
+1
+SELECT binlog_file = @vp_file FROM mysql.backup_history
+WHERE backup_id = @bid;
+binlog_file = @vp_file
+1
+SELECT binlog_pos = @vp_pos FROM mysql.backup_history
+WHERE backup_id = @bid;
+binlog_pos = @vp_pos
+1
+DROP DATABASE db1;
DROP DATABASE IF EXISTS bup_default;
CREATE DATABASE bup_default;
CREATE TABLE bup_default.wide (
=== modified file 'mysql-test/suite/backup/r/backup_errors.result'
--- a/mysql-test/suite/backup/r/backup_errors.result 2008-11-17 09:57:51 +0000
+++ b/mysql-test/suite/backup/r/backup_errors.result 2008-11-25 17:44:19 +0000
@@ -7,19 +7,36 @@ CREATE DATABASE bdb;
CREATE TABLE bdb.t1(a int) ENGINE=MEMORY;
BACKUP DATABASE adb TO '';
ERROR HY000: Malformed file path ''
+SHOW WARNINGS;
+Level Code Message
+Error # Malformed file path ''
BACKUP DATABASE adb TO "bdb/t1.frm";
ERROR HY000: Can't write to backup location 'bdb/t1.frm' (file already exists?)
+SHOW WARNINGS;
+Level Code Message
+Error # Can't write to backup location 'bdb/t1.frm' (file already exists?)
BACKUP DATABASE adb TO "test.bak";
backup_id
#
+SHOW WARNINGS;
+Level Code Message
BACKUP DATABASE adb TO "test.bak";
ERROR HY000: Can't write to backup location 'test.bak' (file already exists?)
+SHOW WARNINGS;
+Level Code Message
+Error # Can't write to backup location 'test.bak' (file already exists?)
DROP DATABASE IF EXISTS foo;
DROP DATABASE IF EXISTS bar;
BACKUP DATABASE foo TO 'test.bak';
ERROR 42000: Unknown database 'foo'
+SHOW WARNINGS;
+Level Code Message
+Error 1049 Unknown database 'foo'
BACKUP DATABASE test,foo,bdb,bar TO 'test.bak';
ERROR 42000: Unknown database 'foo,bar'
+SHOW WARNINGS;
+Level Code Message
+Error # Unknown database 'foo,bar'
BACKUP DATABASE foo,test,bar,foo TO 'test.bak';
ERROR 42000: Not unique database: 'foo'
use adb;
@@ -49,21 +66,39 @@ DROP DATABASE bdb;
Backup of mysql, information_schema scenario 1
BACKUP DATABASE mysql TO 't.bak';
ERROR HY000: Database 'mysql' cannot be included in a backup
+SHOW WARNINGS;
+Level Code Message
+Error # Database 'mysql' cannot be included in a backup
Backup of mysql, information_schema scenario 2
BACKUP DATABASE information_schema TO 't.bak';
ERROR HY000: Database 'information_schema' cannot be included in a backup
+SHOW WARNINGS;
+Level Code Message
+Error # Database 'information_schema' cannot be included in a backup
Backup of mysql, information_schema scenario 3
BACKUP DATABASE mysql, information_schema TO 't.bak';
ERROR HY000: Database 'mysql' cannot be included in a backup
+SHOW WARNINGS;
+Level Code Message
+Error # Database 'mysql' cannot be included in a backup
Backup of mysql, information_schema scenario 4
BACKUP DATABASE mysql, test TO 't.bak';
ERROR HY000: Database 'mysql' cannot be included in a backup
+SHOW WARNINGS;
+Level Code Message
+Error # Database 'mysql' cannot be included in a backup
Backup of mysql, information_schema scenario 5
BACKUP DATABASE information_schema, test TO 't.bak';
ERROR HY000: Database 'information_schema' cannot be included in a backup
+SHOW WARNINGS;
+Level Code Message
+Error # Database 'information_schema' cannot be included in a backup
Backup of mysql, information_schema scenario 6
BACKUP DATABASE mysql, information_schema, test TO 't.bak';
ERROR HY000: Database 'mysql' cannot be included in a backup
+SHOW WARNINGS;
+Level Code Message
+Error # Database 'mysql' cannot be included in a backup
Making copies of progress tables.
CREATE TABLE IF NOT EXISTS test.ob_copy LIKE mysql.backup_history;
CREATE TABLE IF NOT EXISTS test.obp_copy LIKE mysql.backup_progress;
@@ -78,7 +113,7 @@ DROP TABLE mysql.backup_history;
Backup the database;
BACKUP DATABASE test_ob_error TO 'ob_err.bak';
ERROR HY000: Can't open the backup logs as tables. Check 'mysql.backup_history' and
'mysql.backup_progress' or run mysql_upgrade to repair.
-SHOW ERRORS;
+SHOW WARNINGS;
Level Code Message
Error # Table 'mysql.backup_history' doesn't exist
Error # Cannot create backup/restore execution context
@@ -89,7 +124,7 @@ DROP TABLE mysql.backup_progress;
Backup the database;
BACKUP DATABASE test_ob_error TO 'ob_err.bak';
ERROR HY000: Can't open the backup logs as tables. Check 'mysql.backup_history' and
'mysql.backup_progress' or run mysql_upgrade to repair.
-SHOW ERRORS;
+SHOW WARNINGS;
Level Code Message
Error # Table 'mysql.backup_progress' doesn't exist
Error # Cannot create backup/restore execution context
=== modified file 'mysql-test/suite/backup/r/backup_views.result'
--- a/mysql-test/suite/backup/r/backup_views.result 2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_views.result 2008-11-25 17:44:19 +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 HY000: Could not restore view `bup_db1`.`v5`. Please check the view definition for
possible missing dependencies.
+ERROR 42S02: Table 'bup_db2.t2' doesn't exist
DROP DATABASE bup_db1;
RESTORE FROM 'bup_objectview2.bak';
-ERROR HY000: Could not restore view `bup_db2`.`student_details`. Please check the view
definition for possible missing dependencies.
+ERROR 42S02: Table 'bup_db1.t3' doesn't exist
DROP DATABASE bup_db2;
RESTORE FROM 'bup_objectview.bak';
backup_id
=== modified file 'mysql-test/suite/backup/t/backup.test'
--- a/mysql-test/suite/backup/t/backup.test 2008-11-17 09:57:51 +0000
+++ b/mysql-test/suite/backup/t/backup.test 2008-11-26 10:05:19 +0000
@@ -180,11 +180,10 @@ SHOW CREATE TABLE tasking;
# check that VP info was correctly read and reported
-SELECT validity_point_time = @vp_time FROM mysql.backup_history
-WHERE backup_id = @bid;
-SELECT binlog_file = @vp_file FROM mysql.backup_history
-WHERE backup_id = @bid;
-SELECT binlog_pos = @vp_pos FROM mysql.backup_history
+SELECT validity_point_time = @vp_time
+ AND binlog_file = @vp_file
+ AND binlog_pos = @vp_pos
+FROM mysql.backup_history
WHERE backup_id = @bid;
DROP DATABASE db1;
@@ -193,6 +192,51 @@ DROP DATABASE db3;
SET DEBUG_SYNC= 'RESET';
#
+# Check that PTR data (such as VP time and binlog positon) is correctly stored and read
+# when there are no tables to backup (BUG#40262).
+#
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/db1.bkp
+CREATE DATABASE db1;
+
+--replace_column 1 #
+BACKUP DATABASE db1 TO 'db1.bkp';
+# get backup_id of the BACKUP operation.
+SELECT MAX(backup_id) FROM mysql.backup_history INTO @bid;
+
+# store VP time and binlog position
+
+SELECT validity_point_time FROM mysql.backup_history
+WHERE backup_id = @bid INTO @vp_time;
+SELECT binlog_file FROM mysql.backup_history
+WHERE backup_id = @bid INTO @vp_file;
+SELECT binlog_pos FROM mysql.backup_history
+WHERE backup_id = @bid INTO @vp_pos;
+
+DROP DATABASE db1;
+
+# wait few seconds so that restore time != backup time
+--sleep 2
+
+--replace_column 1 #
+RESTORE FROM 'db1.bkp';
+# determine id of RESTORE operation
+SELECT MAX(backup_id) FROM mysql.backup_history INTO @bid;
+
+# check that VP info was correctly read and reported
+
+SELECT validity_point_time = @vp_time
+ AND binlog_file = @vp_file
+ AND binlog_pos = @vp_pos
+FROM mysql.backup_history
+WHERE backup_id = @bid;
+
+DROP DATABASE db1;
+--remove_file $MYSQLTEST_VARDIR/master-data/db1.bkp
+
+
+#
# This test is for the default and snapshot online backup drivers
#
=== modified file 'mysql-test/suite/backup/t/backup_errors.test'
--- a/mysql-test/suite/backup/t/backup_errors.test 2008-11-17 09:57:51 +0000
+++ b/mysql-test/suite/backup/t/backup_errors.test 2008-11-25 17:44:19 +0000
@@ -25,17 +25,25 @@ CREATE TABLE bdb.t1(a int) ENGINE=MEMORY
# invalid location
--error ER_BAD_PATH
BACKUP DATABASE adb TO '';
+--replace_column 2 #
+SHOW WARNINGS;
# don't overwrite existing files
--error ER_BACKUP_WRITE_LOC
BACKUP DATABASE adb TO "bdb/t1.frm";
+--replace_column 2 #
+SHOW WARNINGS;
--replace_column 1 #
BACKUP DATABASE adb TO "test.bak";
+--replace_column 2 #
+SHOW WARNINGS;
# don't overwrite existing backup image
--error ER_BACKUP_WRITE_LOC
BACKUP DATABASE adb TO "test.bak";
+--replace_column 2 #
+SHOW WARNINGS;
--remove_file $MYSQLTEST_VARDIR/master-data/test.bak
@@ -47,8 +55,11 @@ DROP DATABASE IF EXISTS bar;
-- error ER_BAD_DB_ERROR
BACKUP DATABASE foo TO 'test.bak';
+SHOW WARNINGS;
-- error ER_BAD_DB_ERROR
BACKUP DATABASE test,foo,bdb,bar TO 'test.bak';
+--replace_column 2 #
+SHOW WARNINGS;
# repeated database
-- error ER_NONUNIQ_DB
@@ -117,6 +128,8 @@ DROP DATABASE bdb;
--echo Backup of mysql, information_schema scenario 1
--error ER_BACKUP_CANNOT_INCLUDE_DB
BACKUP DATABASE mysql TO 't.bak';
+--replace_column 2 #
+SHOW WARNINGS;
--error 0, 1
--remove_file $MYSQLTEST_VARDIR/master-data/t.bak
@@ -125,6 +138,8 @@ BACKUP DATABASE mysql TO 't.bak';
--echo Backup of mysql, information_schema scenario 2
--error ER_BACKUP_CANNOT_INCLUDE_DB
BACKUP DATABASE information_schema TO 't.bak';
+--replace_column 2 #
+SHOW WARNINGS;
--error 0, 1
--remove_file $MYSQLTEST_VARDIR/master-data/t.bak
@@ -133,6 +148,8 @@ BACKUP DATABASE information_schema TO 't
--echo Backup of mysql, information_schema scenario 3
--error ER_BACKUP_CANNOT_INCLUDE_DB
BACKUP DATABASE mysql, information_schema TO 't.bak';
+--replace_column 2 #
+SHOW WARNINGS;
--error 0, 1
--remove_file $MYSQLTEST_VARDIR/master-data/t.bak
@@ -141,6 +158,8 @@ BACKUP DATABASE mysql, information_schem
--echo Backup of mysql, information_schema scenario 4
--error ER_BACKUP_CANNOT_INCLUDE_DB
BACKUP DATABASE mysql, test TO 't.bak';
+--replace_column 2 #
+SHOW WARNINGS;
--error 0, 1
--remove_file $MYSQLTEST_VARDIR/master-data/t.bak
@@ -149,6 +168,8 @@ BACKUP DATABASE mysql, test TO 't.bak';
--echo Backup of mysql, information_schema scenario 5
--error ER_BACKUP_CANNOT_INCLUDE_DB
BACKUP DATABASE information_schema, test TO 't.bak';
+--replace_column 2 #
+SHOW WARNINGS;
--error 0, 1
--remove_file $MYSQLTEST_VARDIR/master-data/t.bak
@@ -157,6 +178,8 @@ BACKUP DATABASE information_schema, test
--echo Backup of mysql, information_schema scenario 6
--error ER_BACKUP_CANNOT_INCLUDE_DB
BACKUP DATABASE mysql, information_schema, test TO 't.bak';
+--replace_column 2 #
+SHOW WARNINGS;
--error 0, 1
--remove_file $MYSQLTEST_VARDIR/master-data/t.bak
@@ -190,7 +213,7 @@ BACKUP DATABASE test_ob_error TO 'ob_err
--error 0,1
--remove_file $MYSQLTEST_VARDIR/master-data/ob_err.bak
--replace_column 2 #
-SHOW ERRORS;
+SHOW WARNINGS;
# Restore the table
--echo Restoring the table
@@ -207,7 +230,7 @@ BACKUP DATABASE test_ob_error TO 'ob_err
--error 0,1
--remove_file $MYSQLTEST_VARDIR/master-data/ob_err.bak
--replace_column 2 #
-SHOW ERRORS;
+SHOW WARNINGS;
# Restore the table
--echo Restoring the table
=== modified file 'mysql-test/suite/backup/t/backup_myisam1.test'
--- a/mysql-test/suite/backup/t/backup_myisam1.test 2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_myisam1.test 2008-11-25 17:44:19 +0000
@@ -24,5 +24,7 @@ BACKUP DATABASE mysqltest TO 'test.ba';
# Cleanup from this test case
#
DROP DATABASE mysqltest;
+# Note: The backup file should not exist as BACKUP command failed.
+--error 1
--remove_file $MYSQLTEST_VARDIR/master-data/test.ba
=== modified file 'mysql-test/suite/backup/t/backup_views.test'
--- a/mysql-test/suite/backup/t/backup_views.test 2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_views.test 2008-11-25 17:44:19 +0000
@@ -205,14 +205,14 @@ DROP DATABASE bup_db2;
--echo restore database with view dependency to other, non-existing db
---error ER_BACKUP_CANT_RESTORE_VIEW
+--error ER_NO_SUCH_TABLE
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_BACKUP_CANT_RESTORE_VIEW
+--error ER_NO_SUCH_TABLE
RESTORE FROM 'bup_objectview2.bak';
# An incomplete bup_db2 was created by the failing restore operation.
=== modified file 'sql/backup/backup_info.cc'
--- a/sql/backup/backup_info.cc 2008-11-05 09:41:15 +0000
+++ b/sql/backup/backup_info.cc 2008-11-25 17:44:19 +0000
@@ -87,11 +87,11 @@ Backup_info::find_backup_engine(const ba
// See if table has native backup engine
- storage_engine_ref se= get_storage_engine(m_ctx.m_thd, tbl);
+ storage_engine_ref se= get_storage_engine(m_thd, tbl);
if (!se)
{
- m_ctx.fatal_error(ER_NO_STORAGE_ENGINE, tbl.describe(buf));
+ m_log.report_error(ER_NO_STORAGE_ENGINE, tbl.describe(buf));
DBUG_RETURN(NULL);
}
@@ -126,7 +126,7 @@ Backup_info::find_backup_engine(const ba
if (!snap)
if (has_native_backup(se))
{
- Native_snapshot *nsnap= new Native_snapshot(m_ctx, se);
+ Native_snapshot *nsnap= new Native_snapshot(m_log, se);
/*
Check if the snapshot object is valid - in particular has successfully
@@ -175,7 +175,7 @@ Backup_info::find_backup_engine(const ba
}
if (!snap)
- m_ctx.fatal_error(ER_BACKUP_NO_BACKUP_DRIVER,tbl.describe(buf));
+ m_log.report_error(ER_BACKUP_NO_BACKUP_DRIVER,tbl.describe(buf));
DBUG_RETURN(snap);
}
@@ -295,13 +295,16 @@ Backup_info::Dep_node::get_key(const uch
/**
Create @c Backup_info instance and prepare it for populating with objects.
-
+
+ @param[in] log A logger used to report errors
+ @param[in] thd THD handle
+
Snapshots created by the built-in backup engines are added to @c snapshots
list to be used in the backup engine selection algorithm in
@c find_backup_engine().
*/
-Backup_info::Backup_info(Backup_restore_ctx &ctx)
- :m_ctx(ctx), m_state(Backup_info::ERROR), native_snapshots(8),
+Backup_info::Backup_info(backup::Logger &log, THD *thd)
+ :m_log(log), m_thd(thd), 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_event_end(NULL)
{
@@ -318,7 +321,7 @@ Backup_info::Backup_info(Backup_restore_
Dep_node::get_key, Dep_node::free, MYF(0)))
{
// Allocation failed. Error has been reported, but not logged to backup logs
- m_ctx.log_error(ER_OUT_OF_RESOURCES);
+ m_log.log_error(ER_OUT_OF_RESOURCES);
return;
}
@@ -328,10 +331,10 @@ Backup_info::Backup_info(Backup_restore_
element on that list, as a "catch all" entry.
*/
- snap= new Nodata_snapshot(m_ctx); // logs errors
+ snap= new Nodata_snapshot(m_log); // logs errors
if (!snap)
{
- m_ctx.fatal_error(ER_OUT_OF_RESOURCES);
+ m_log.report_error(ER_OUT_OF_RESOURCES);
return;
}
@@ -341,14 +344,14 @@ Backup_info::Backup_info(Backup_restore_
if (snapshots.push_back(snap))
{
// Allocation failed. Error has been reported, but not logged to backup logs
- m_ctx.log_error(ER_OUT_OF_RESOURCES);
+ m_log.log_error(ER_OUT_OF_RESOURCES);
return;
}
- snap= new CS_snapshot(m_ctx); // logs errors
+ snap= new CS_snapshot(m_log); // logs errors
if (!snap)
{
- m_ctx.fatal_error(ER_OUT_OF_RESOURCES);
+ m_log.report_error(ER_OUT_OF_RESOURCES);
return;
}
@@ -358,14 +361,14 @@ Backup_info::Backup_info(Backup_restore_
if (snapshots.push_back(snap))
{
// Allocation failed. Error has been reported, but not logged to backup logs
- m_ctx.log_error(ER_OUT_OF_RESOURCES);
+ m_log.log_error(ER_OUT_OF_RESOURCES);
return; // Error has been logged
}
- snap= new Default_snapshot(m_ctx); // logs errors
+ snap= new Default_snapshot(m_log); // logs errors
if (!snap)
{
- m_ctx.fatal_error(ER_OUT_OF_RESOURCES);
+ m_log.report_error(ER_OUT_OF_RESOURCES);
return;
}
@@ -375,7 +378,7 @@ Backup_info::Backup_info(Backup_restore_
if (snapshots.push_back(snap))
{
// Allocation failed. Error has been reported, but not logged to backup logs
- m_ctx.log_error(ER_OUT_OF_RESOURCES);
+ m_log.log_error(ER_OUT_OF_RESOURCES);
return; // Error has been logged
}
@@ -417,7 +420,7 @@ int Backup_info::close()
// report backup drivers used in the image
for (ushort n=0; n < snap_count(); ++n)
- m_ctx.report_driver(m_snap[n]->name());
+ m_log.report_driver(m_snap[n]->name());
m_state= CLOSED;
return 0;
@@ -465,7 +468,7 @@ backup::Image_info::Ts* Backup_info::add
if (!ts)
{
- m_ctx.fatal_error(ER_BACKUP_CATALOG_ADD_TS, name);
+ m_log.report_error(ER_BACKUP_CATALOG_ADD_TS, name);
return NULL;
}
@@ -479,7 +482,7 @@ backup::Image_info::Ts* Backup_info::add
if (!n1)
{
- m_ctx.fatal_error(ER_OUT_OF_RESOURCES);
+ m_log.report_error(ER_OUT_OF_RESOURCES);
return NULL;
}
@@ -513,7 +516,7 @@ backup::Image_info::Db* Backup_info::add
if (!db)
{
- m_ctx.fatal_error(ER_BACKUP_CATALOG_ADD_DB, name->ptr());
+ m_log.report_error(ER_BACKUP_CATALOG_ADD_DB, name->ptr());
return NULL;
}
@@ -550,7 +553,7 @@ int Backup_info::add_dbs(List< ::LEX_STR
if (is_internal_db_name(&db_name))
{
- m_ctx.fatal_error(ER_BACKUP_CANNOT_INCLUDE_DB, db_name.c_ptr());
+ m_log.report_error(ER_BACKUP_CANNOT_INCLUDE_DB, db_name.c_ptr());
goto error;
}
@@ -589,7 +592,7 @@ int Backup_info::add_dbs(List< ::LEX_STR
if (!unknown_dbs.is_empty())
{
- m_ctx.fatal_error(ER_BAD_DB_ERROR, unknown_dbs.c_ptr());
+ m_log.report_error(ER_BAD_DB_ERROR, unknown_dbs.c_ptr());
goto error;
}
@@ -614,11 +617,11 @@ int Backup_info::add_all_dbs()
using namespace obs;
int res= 0;
- Obj_iterator *dbit= get_databases(m_ctx.m_thd);
+ Obj_iterator *dbit= get_databases(m_thd);
if (!dbit)
{
- m_ctx.fatal_error(ER_BACKUP_LIST_DBS);
+ m_log.report_error(ER_BACKUP_LIST_DBS);
return ERROR;
}
@@ -701,11 +704,11 @@ int Backup_info::add_db_items(Db &db)
// Add tables.
- Obj_iterator *it= get_db_tables(m_ctx.m_thd, &db.name());
+ Obj_iterator *it= get_db_tables(m_thd, &db.name());
if (!it)
{
- m_ctx.fatal_error(ER_BACKUP_LIST_DB_TABLES, db.name().ptr());
+ m_log.report_error(ER_BACKUP_LIST_DB_TABLES, db.name().ptr());
return ERROR;
}
@@ -731,7 +734,7 @@ int Backup_info::add_db_items(Db &db)
// If this table uses a tablespace, add this tablespace to the catalogue.
- obj= get_tablespace_for_table(m_ctx.m_thd, &db.name(), &tbl->name());
+ obj= get_tablespace_for_table(m_thd, &db.name(), &tbl->name());
if (obj)
{
@@ -748,11 +751,11 @@ int Backup_info::add_db_items(Db &db)
// Add other objects.
delete it;
- it= get_db_stored_procedures(m_ctx.m_thd, &db.name());
+ it= get_db_stored_procedures(m_thd, &db.name());
if (!it)
{
- m_ctx.fatal_error(ER_BACKUP_LIST_DB_SROUT, db.name().ptr());
+ m_log.report_error(ER_BACKUP_LIST_DB_SROUT, db.name().ptr());
goto error;
}
@@ -760,11 +763,11 @@ int Backup_info::add_db_items(Db &db)
goto error;
delete it;
- it= get_db_stored_functions(m_ctx.m_thd, &db.name());
+ it= get_db_stored_functions(m_thd, &db.name());
if (!it)
{
- m_ctx.fatal_error(ER_BACKUP_LIST_DB_SROUT, db.name().ptr());
+ m_log.report_error(ER_BACKUP_LIST_DB_SROUT, db.name().ptr());
goto error;
}
@@ -772,11 +775,11 @@ int Backup_info::add_db_items(Db &db)
goto error;
delete it;
- it= get_db_views(m_ctx.m_thd, &db.name());
+ it= get_db_views(m_thd, &db.name());
if (!it)
{
- m_ctx.fatal_error(ER_BACKUP_LIST_DB_VIEWS, db.name().ptr());
+ m_log.report_error(ER_BACKUP_LIST_DB_VIEWS, db.name().ptr());
goto error;
}
@@ -784,11 +787,11 @@ int Backup_info::add_db_items(Db &db)
goto error;
delete it;
- it= get_db_events(m_ctx.m_thd, &db.name());
+ it= get_db_events(m_thd, &db.name());
if (!it)
{
- m_ctx.fatal_error(ER_BACKUP_LIST_DB_EVENTS, db.name().ptr());
+ m_log.report_error(ER_BACKUP_LIST_DB_EVENTS, db.name().ptr());
goto error;
}
@@ -796,11 +799,11 @@ int Backup_info::add_db_items(Db &db)
goto error;
delete it;
- it= get_db_triggers(m_ctx.m_thd, &db.name());
+ it= get_db_triggers(m_thd, &db.name());
if (!it)
{
- m_ctx.fatal_error(ER_BACKUP_LIST_DB_TRIGGERS, db.name().ptr());
+ m_log.report_error(ER_BACKUP_LIST_DB_TRIGGERS, db.name().ptr());
goto error;
}
@@ -808,11 +811,11 @@ int Backup_info::add_db_items(Db &db)
goto error;
delete it;
- it= get_all_db_grants(m_ctx.m_thd, &db.name());
+ it= get_all_db_grants(m_thd, &db.name());
if (!it)
{
- m_ctx.fatal_error(ER_BACKUP_LIST_DB_PRIV, db.name().ptr());
+ m_log.report_error(ER_BACKUP_LIST_DB_PRIV, db.name().ptr());
goto error;
}
@@ -889,8 +892,8 @@ backup::Image_info::Table* Backup_info::
if (!tbl)
{
- m_ctx.fatal_error(ER_BACKUP_CATALOG_ADD_TABLE,
- dbi.name().ptr(), t.name().ptr());
+ m_log.report_error(ER_BACKUP_CATALOG_ADD_TABLE,
+ dbi.name().ptr(), t.name().ptr());
return NULL;
}
@@ -943,7 +946,7 @@ int Backup_info::add_view_deps(obs::Obj
// Get an iterator to iterate over base views of the given one.
- obs::Obj_iterator *it= obs::get_view_base_views(m_ctx.m_thd, db_name, name);
+ obs::Obj_iterator *it= obs::get_view_base_views(m_thd, db_name, name);
if (!it)
return ERROR;
@@ -1086,7 +1089,7 @@ Backup_info::add_db_object(Db &db, const
if (res == get_dep_node_res::ERROR)
{
- m_ctx.fatal_error(error, db.name().ptr(), name->ptr());
+ m_log.report_error(error, db.name().ptr(), name->ptr());
return NULL;
}
@@ -1101,7 +1104,7 @@ Backup_info::add_db_object(Db &db, const
if (type == BSTREAM_IT_VIEW)
if (add_view_deps(*obj))
{
- m_ctx.fatal_error(error, db.name().ptr(), name->ptr());
+ m_log.report_error(error, db.name().ptr(), name->ptr());
return NULL;
}
@@ -1122,7 +1125,7 @@ Backup_info::add_db_object(Db &db, const
if (!o)
{
- m_ctx.fatal_error(error, db.name().ptr(), name->ptr());
+ m_log.report_error(error, db.name().ptr(), name->ptr());
return NULL;
}
@@ -1342,7 +1345,7 @@ int Backup_info::Global_iterator::init()
if (!m_it)
{
const Backup_info* info= static_cast<const Backup_info*>(&m_info);
- return info->m_ctx.fatal_error(ER_OUT_OF_RESOURCES);
+ return info->m_log.report_error(ER_OUT_OF_RESOURCES);
}
next(); // Never errors
@@ -1388,7 +1391,7 @@ Backup_info::Global_iterator::next()
if (!m_it)
{
const Backup_info* info= static_cast<const Backup_info*>(&m_info);
- info->m_ctx.fatal_error(ER_OUT_OF_RESOURCES);
+ info->m_log.report_error(ER_OUT_OF_RESOURCES);
mode= DONE;
return FALSE;
}
@@ -1471,7 +1474,7 @@ backup::Image_info::Iterator* Backup_inf
Global_iterator* it = new Global_iterator(*this);
if (it == NULL)
{
- m_ctx.fatal_error(ER_OUT_OF_RESOURCES);
+ m_log.report_error(ER_OUT_OF_RESOURCES);
return NULL;
}
if (it->init()) // Error has been logged
@@ -1488,7 +1491,7 @@ backup::Image_info::Iterator* Backup_inf
Perdb_iterator* it = new Perdb_iterator(*this);
if (it == NULL)
{
- m_ctx.fatal_error(ER_OUT_OF_RESOURCES);
+ m_log.report_error(ER_OUT_OF_RESOURCES);
return NULL;
}
if (it->init()) // Error has been logged
=== modified file 'sql/backup/backup_info.h'
--- a/sql/backup/backup_info.h 2008-11-13 13:02:36 +0000
+++ b/sql/backup/backup_info.h 2008-11-25 17:44:19 +0000
@@ -31,9 +31,8 @@ class Backup_info: public backup::Image_
{
public:
- Backup_restore_ctx &m_ctx;
+ backup::Logger &m_log;
- Backup_info(Backup_restore_ctx&);
~Backup_info();
bool is_valid();
@@ -48,10 +47,18 @@ class Backup_info: public backup::Image_
private:
+ /*
+ Note: constructor is private because instances of this class are supposed
+ to be created only with Backup_restore_ctx::prepare_for_backup() method.
+ */
+ Backup_info(backup::Logger&, THD*);
+
// Prevent copying/assignments
Backup_info(const Backup_info&);
Backup_info& operator=(const Backup_info&);
+ THD *m_thd;
+
class Global_iterator; ///< Iterates over global items (for which meta-data is
stored).
class Perdb_iterator; ///< Iterates over all per-database objects (except tables).
@@ -169,6 +176,7 @@ class Backup_info: public backup::Image_
friend int ::bcat_get_item_create_query(st_bstream_image_header *catalogue,
struct st_bstream_item_info *item,
bstream_blob *stmt);
+ friend class Backup_restore_ctx; // Needs access to the constructor.
};
/// Check if instance is correctly created.
=== modified file 'sql/backup/backup_kernel.h'
--- a/sql/backup/backup_kernel.h 2008-11-17 09:57:51 +0000
+++ b/sql/backup/backup_kernel.h 2008-11-25 17:44:19 +0000
@@ -75,8 +75,6 @@ class Backup_restore_ctx: public backup:
int do_backup();
int do_restore(bool overwrite);
- int fatal_error(int, ...);
- int log_error(int, ...);
int close();
@@ -102,7 +100,8 @@ class Backup_restore_ctx: public backup:
/**
@brief State of a context object.
- Backup/restore can be performed only if object is prepared for that operation.
+ Backup/restore can be performed only if object is prepared for that
+ operation.
*/
enum { CREATED,
PREPARED_FOR_BACKUP,
@@ -111,10 +110,22 @@ class Backup_restore_ctx: public backup:
ulonglong m_thd_options; ///< For saving thd->options.
/**
- If backup/restore was interrupted by an error, this member stores the error
- number.
- */
+ @brief Tells if context object is in error state.
+
+ In case of fatal error, the context object is put into an error state
+ by setting @m_error to non-zero value. This can be the code of
+ the detected error but currently the exact value is not used.
+
+ When in error state, public methods of Backup_restore_ctx do not try
+ to perform their operations but report an error instead. @c Is_valid()
+ will return FALSE for an object in error state.
+
+ @note The error state is an internal state of the context object. The
+ object can enter this state only as a result of executing one of its
+ methods.
+ */
int m_error;
+ int fatal_error(int);
::String m_path; ///< Path to where the backup image file is located.
@@ -149,8 +160,6 @@ class Backup_restore_ctx: public backup:
int report_stream_open_failure(int open_error, const LEX_STRING *location);
- friend class Backup_info;
- friend class Restore_info;
friend int backup_init();
friend void backup_shutdown();
friend bstream_byte* bstream_alloc(unsigned long int);
@@ -179,32 +188,31 @@ void Backup_restore_ctx::disable_fkey_co
}
/**
- Report error and move context object into error state.
+ Move context object into error state.
After this method is called the context object is in error state and
- cannot be normally used. It still can be examined for saved error messages.
- The code of the error reported here is saved in m_error member.
+ cannot be normally used. The provided error code is saved in m_error
+ member.
Only one fatal error can be reported. If context is already in error
state when this method is called, it does nothing.
+
+ @note Context object should enter error state only as a result of executing
+ one of its methods. Thus this private helper method is intended to be used
+ only from within Backup_restore_ctx class.
@return error code given as input or stored in the context object if
- a fatal error was reported before.
+ it is already in error state.
*/
inline
-int Backup_restore_ctx::fatal_error(int error_code, ...)
+int Backup_restore_ctx::fatal_error(int error_code)
{
+ m_remove_loc= TRUE;
+
if (m_error)
return m_error;
- va_list args;
-
m_error= error_code;
- m_remove_loc= TRUE;
-
- va_start(args,error_code);
- v_report_error(backup::log_level::ERROR, error_code, args);
- va_end(args);
return error_code;
}
=== modified file 'sql/backup/data_backup.cc'
--- a/sql/backup/data_backup.cc 2008-10-30 20:02:15 +0000
+++ b/sql/backup/data_backup.cc 2008-11-26 10:05:19 +0000
@@ -248,7 +248,7 @@ class Scheduler
private:
LIST *m_pumps, *m_last;
- Logger *m_log; ///< used to report errors if not NULL
+ Logger &m_log; ///< for reporting errors
uint m_count; ///< current number of pumps
size_t m_total; ///< accumulated position of all drivers
size_t m_init_left; ///< how much of init data is left (estimate)
@@ -256,7 +256,7 @@ class Scheduler
Output_stream &m_str; ///< stream to which we write
bool cancelled; ///< true if backup process was cancelled
- Scheduler(Output_stream &s, Logger *log)
+ Scheduler(Output_stream &s, Logger &log)
:init_count(0), prepare_count(0), finish_count(0),
m_pumps(NULL), m_last(NULL), m_log(log),
m_count(0), m_total(0), m_init_left(0), m_known_count(0),
@@ -412,6 +412,70 @@ int unblock_commits(THD *thd)
}
/**
+ Store information about validity point in @c Backup_info structure.
+
+ @note This function is called in a time critical synchronization phase
+ of the backup process. Therefore it should not perform any time consuming
+ or potentially waiting operations such as I/O.
+
+ @returns 0 on success.
+*/
+static
+int save_vp_info(Backup_info &info)
+{
+ LOG_INFO binlog_pos;
+ int ret=0;
+
+ /*
+ Save VP creation time.
+ */
+ info.save_vp_time(my_time(0));
+
+ /*
+ Save current binlog position if it is enabled.
+ */
+ if (mysql_bin_log.is_open())
+ if (mysql_bin_log.get_current_log(&binlog_pos))
+ {
+ info.m_log.report_error(ER_BACKUP_BINLOG);
+ ret= TRUE;
+ }
+ else
+ info.save_binlog_pos(binlog_pos);
+
+ /*
+ Save master's binlog information if we are a connected slave.
+ */
+ if (obs::is_slave() && active_mi)
+ info.save_master_pos(*active_mi);
+
+ return ret;
+}
+
+/**
+ Log validity point information.
+
+ Information such as validity point time is logged using backup logger which,
+ in particular, writes it to backup history and progress logs.
+
+ @note Logging the information may involve time consuming I/O. Therefore this
+ function should not be called in the time critical synchronization phase, but
+ after the synchronisation has been done.
+*/
+static
+void report_vp_info(Backup_info &info)
+{
+ info.m_log.report_vp_time(info.get_vp_time(),
+ TRUE // = also write to progress log
+ );
+ if (info.flags & BSTREAM_FLAG_BINLOG)
+ info.m_log.report_binlog_pos(info.binlog_pos);
+ if (info.master_pos.pos)
+ info.m_log.report_master_binlog_pos(info.master_pos);
+}
+
+
+/**
Save data from tables being backed up.
Function initializes and controls backup drivers which create the image
@@ -424,17 +488,30 @@ int write_table_data(THD* thd, Backup_in
{
DBUG_ENTER("backup::write_table_data");
+ /*
+ If there are no tables to backup, there is nothing to do in this function
+ except for storing and reporting the validity point info.
+
+ Note that since DDLs are disabled and backup image contains no table data,
+ any time during backup operation is a good validity time -- there is no
+ issue of synchronising the data stored in the image with the data in the
+ rest of the server.
+ */
if (info.snap_count() == 0 || info.table_count() == 0) // nothing to backup
- DBUG_RETURN(0);
+ {
+ int res= save_vp_info(info); // logs errors
+ if (!res)
+ report_vp_info(info);
+ DBUG_RETURN(res);
+ }
- Scheduler sch(s, &info.m_ctx); // scheduler instance
+ Logger &log= info.m_log;
+ Scheduler sch(s, log); // scheduler instance
List<Scheduler::Pump> inactive; // list of images not yet being created
// keeps maximal init size for images in inactive list
size_t max_init_size=0;
- time_t vp_time; // to store validity point time
-
DBUG_PRINT("backup_data",("initializing scheduler"));
// add unknown "at end" drivers to scheduler, rest to inactive list
@@ -448,9 +525,15 @@ int write_table_data(THD* thd, Backup_in
Scheduler::Pump *p= new Scheduler::Pump(*i, s);
- if (!p || !p->is_valid())
+ if (!p)
{
- info.m_ctx.fatal_error(ER_OUT_OF_RESOURCES);
+ log.report_error(ER_OUT_OF_RESOURCES);
+ goto error;
+ }
+ if (!p->is_valid())
+ {
+ log.report_error(ER_BACKUP_CREATE_BACKUP_DRIVER,p->m_name);
+ delete p;
goto error;
}
@@ -458,7 +541,7 @@ int write_table_data(THD* thd, Backup_in
if (init_size == Driver::UNKNOWN_SIZE)
{
- if (sch.add(p))
+ if (sch.add(p)) // logs errors
goto error;
}
else
@@ -471,7 +554,7 @@ int write_table_data(THD* thd, Backup_in
/* Allocation failed.
Error has been reported, but not logged to backup logs.
*/
- info.m_ctx.log_error(ER_OUT_OF_RESOURCES);
+ log.log_error(ER_OUT_OF_RESOURCES);
goto error;
}
}
@@ -529,7 +612,7 @@ int write_table_data(THD* thd, Backup_in
// poll drivers
- if (sch.step())
+ if (sch.step()) // logs errors
goto error;
}
@@ -571,7 +654,7 @@ int write_table_data(THD* thd, Backup_in
if (error)
goto error;
- if (sch.prepare())
+ if (sch.prepare()) // logs errors
goto error;
while (sch.prepare_count > 0)
@@ -582,9 +665,7 @@ int write_table_data(THD* thd, Backup_in
DBUG_PRINT("backup_data",("-- SYNC PHASE --"));
- LOG_INFO binlog_pos;
-
- info.m_ctx.report_state(BUP_VALIDITY_POINT);
+ log.report_state(BUP_VALIDITY_POINT);
/*
This breakpoint is used to assist in testing state changes for
the backup progress. It is not to be used to indicate actual
@@ -597,39 +678,13 @@ int write_table_data(THD* thd, Backup_in
*/
DEBUG_SYNC(thd, "before_backup_data_lock");
- if (sch.lock())
+ if (sch.lock()) // logs errors
goto error;
- /*
- Save binlog information for point in time recovery on restore.
- */
- if (mysql_bin_log.is_open())
- if (mysql_bin_log.get_current_log(&binlog_pos))
- {
- info.m_ctx.fatal_error(ER_BACKUP_BINLOG);
- goto error;
- }
-
- /*
- If we are a connected slave, write master's binlog information to
- the progress log for later use.
- */
- st_bstream_binlog_pos master_pos;
- master_pos.pos= 0;
- master_pos.file= 0;
- if (obs::is_slave() && active_mi)
- {
- master_pos.pos= (ulong)active_mi->master_log_pos;
- master_pos.file= active_mi->master_log_name;
- }
-
- /*
- Save VP creation time.
- */
- vp_time= my_time(0);
+ save_vp_info(info);
DEBUG_SYNC(thd, "before_backup_data_unlock");
- if (sch.unlock())
+ if (sch.unlock()) // logs errors
goto error;
/*
@@ -640,25 +695,9 @@ int write_table_data(THD* thd, Backup_in
if (error)
goto error;
- // Report and save information about VP
-
- info.save_vp_time(vp_time);
- info.m_ctx.report_vp_time(vp_time, TRUE); // TRUE = also write to progress log
-
- if (mysql_bin_log.is_open())
- {
- info.save_binlog_pos(binlog_pos);
- info.m_ctx.report_binlog_pos(info.binlog_pos);
- }
+ report_vp_info(info);
- /*
- If we are a slave and the master's binlog position has been recorded
- write it to the log.
- */
- if (obs::is_slave() && master_pos.pos)
- info.m_ctx.report_master_binlog_pos(master_pos);
-
- info.m_ctx.report_state(BUP_RUNNING);
+ log.report_state(BUP_RUNNING);
DEBUG_SYNC(thd, "after_backup_binlog");
/**** VP creation (end) ********************************************/
@@ -819,9 +858,6 @@ int Scheduler::step()
case backup_state::ERROR:
remove_pump(p); // Note: never errors.
- if (res)
- cancel_backup(); // we hit an error - bail out
- // Note: cancel_backup() never errors.
break;
default: break;
@@ -846,11 +882,14 @@ int Scheduler::add(Pump *p)
if (!p) // no pump to add
return 0;
- p->set_logger(m_log);
+ p->set_logger(&m_log);
p->start_pos= avg;
- if (p->begin())
- goto error;
+ if (p->begin()) // logs errors
+ {
+ delete p;
+ return ERROR;
+ }
// in case of error, above call should return non-zero code (and report error)
DBUG_ASSERT(p->state != backup_state::ERROR);
@@ -894,12 +933,6 @@ int Scheduler::add(Pump *p)
(unsigned long)m_init_left));
return 0;
-
- error:
-
- delete p;
- cancel_backup();
- return ERROR;
}
/// Move backup pump to the end of scheduler's list.
@@ -971,9 +1004,9 @@ int Scheduler::prepare()
for (Pump_iterator it(*this); it; ++it)
{
- if (it->prepare())
+ if (it->prepare()) // logs errors
{
- cancel_backup(); // Note: never errors.
+ remove_pump(it); // Note: never errors.
return ERROR;
}
if (it->state == backup_state::PREPARING)
@@ -994,9 +1027,9 @@ int Scheduler::lock()
DBUG_PRINT("backup_data",("calling lock() for all drivers"));
for (Pump_iterator it(*this); it; ++it)
- if (it->lock())
+ if (it->lock()) // logs errors
{
- cancel_backup(); // Note: never errors.
+ remove_pump(it); // Note: never errors.
return ERROR;
}
@@ -1013,9 +1046,9 @@ int Scheduler::unlock()
for(Pump_iterator it(*this); it; ++it)
{
- if (it->unlock())
+ if (it->unlock()) // logs errors
{
- cancel_backup(); // Note: never errors.
+ remove_pump(it); // Note: never errors.
return ERROR;
}
if (it->state == backup_state::FINISHING)
@@ -1072,9 +1105,7 @@ int Backup_pump::begin()
if (ERROR == m_drv->begin(m_bw.buf_size))
{
state= backup_state::ERROR;
- // We check if logger is always setup. Later the assertion can
- // be replaced with "if (m_log)"
- DBUG_ASSERT(m_log);
+ if (m_log)
m_log->report_error(ER_BACKUP_INIT_BACKUP_DRIVER, m_name);
return ERROR;
}
@@ -1092,7 +1123,7 @@ int Backup_pump::end()
if (ERROR == m_drv->end())
{
state= backup_state::ERROR;
- DBUG_ASSERT(m_log);
+ if (m_log)
m_log->report_error(ER_BACKUP_STOP_BACKUP_DRIVER, m_name);
return ERROR;
}
@@ -1121,9 +1152,9 @@ int Backup_pump::prepare()
case ERROR:
default:
state= backup_state::ERROR;
- DBUG_ASSERT(m_log);
+ if (m_log)
m_log->report_error(ER_BACKUP_PREPARE_DRIVER, m_name);
- return ERROR;
+ return ERROR;
}
DBUG_PRINT("backup_data",(" preparing %s, goes to %s state",
@@ -1138,7 +1169,7 @@ int Backup_pump::lock()
if (ERROR == m_drv->lock())
{
state= backup_state::ERROR;
- DBUG_ASSERT(m_log);
+ if (m_log)
m_log->report_error(ER_BACKUP_CREATE_VP, m_name);
return ERROR;
}
@@ -1154,7 +1185,7 @@ int Backup_pump::unlock()
if (ERROR == m_drv->unlock())
{
state= backup_state::ERROR;
- DBUG_ASSERT(m_log);
+ if (m_log)
m_log->report_error(ER_BACKUP_UNLOCK_DRIVER, m_name);
return ERROR;
}
@@ -1167,7 +1198,7 @@ int Backup_pump::cancel()
if (ERROR == m_drv->cancel())
{
state= backup_state::ERROR;
- DBUG_ASSERT(m_log);
+ if (m_log)
m_log->report_error(ER_BACKUP_CANCEL_BACKUP, m_name);
return ERROR;
}
@@ -1248,7 +1279,7 @@ int Backup_pump::pump(size_t *howmuch)
case Block_writer::ERROR:
default:
- DBUG_ASSERT(m_log);
+ if (m_log)
m_log->report_error(ER_BACKUP_GET_BUF);
state= backup_state::ERROR;
return ERROR;
@@ -1293,7 +1324,7 @@ int Backup_pump::pump(size_t *howmuch)
case ERROR:
default:
- DBUG_ASSERT(m_log);
+ if (m_log)
m_log->report_error(ER_BACKUP_GET_DATA, m_name);
state= backup_state::ERROR;
return ERROR;
@@ -1328,7 +1359,7 @@ int Backup_pump::pump(size_t *howmuch)
case Block_writer::ERROR:
- DBUG_ASSERT(m_log);
+ if (m_log)
m_log->report_error(ER_BACKUP_WRITE_DATA, m_name, m_buf.table_num);
state= backup_state::ERROR;
return ERROR;
@@ -1364,18 +1395,50 @@ namespace backup {
*/
int restore_table_data(THD *thd, Restore_info &info, Input_stream &s)
{
+ st_bstream_data_chunk chunk_info; // For reading chunks from the stream.
+
DBUG_ENTER("restore::restore_table_data");
enum { READING, SENDING, DONE, ERROR } state= READING;
+ /*
+ If there are no tables stored in the image, there is nothing to do in this
+ function. However, we must call bstream_rd_data_chunk() which will absorb
+ the 0x00 byte signalling end of (the empty) table data chunk sequence.
+ */
if (info.snap_count() == 0 || info.table_count() == 0) // nothing to restore
+ {
+ int res= bstream_rd_data_chunk(&s, &chunk_info);
+ if (res != BSTREAM_EOC)
+ {
+ info.m_log.report_error(res == BSTREAM_ERROR ?
+ ER_BACKUP_READ_DATA :
+ ER_BACKUP_UNEXPECTED_DATA);
+ DBUG_RETURN(ERROR);
+ }
DBUG_RETURN(0);
+ }
- Restore_driver* drv[256];
+ Logger &log= info.m_log;
- if (info.snap_count() > 256)
+ /* Drv[n] points at restore driver used to process snapshot n. */
+ Restore_driver* drv[MAX_SNAP_COUNT];
+ /*
+ Active[n] is not NULL if driver drv[n] has been activated. Such driver needs
+ an end() or cancel() call to shut it down properly.
+ */
+ Restore_driver* active[MAX_SNAP_COUNT];
+ /*
+ Bad_drivers string for holding comma separated list of drivers which
+ signalled errors during shutdown. If non-empty, an error will be logged
+ at the end of the function (finish: label).
+ */
+ String bad_drivers;
+
+ if (info.snap_count() > MAX_SNAP_COUNT)
{
- info.m_ctx.fatal_error(ER_BACKUP_TOO_MANY_IMAGES, info.snap_count(), 256);
+ log.report_error(ER_BACKUP_TOO_MANY_IMAGES,
+ info.snap_count(), MAX_SNAP_COUNT);
DBUG_RETURN(ERROR);
}
@@ -1384,7 +1447,7 @@ int restore_table_data(THD *thd, Restore
for (uint n=0; n < info.snap_count(); ++n)
{
- drv[n]= NULL;
+ active[n]= drv[n]= NULL;
Snapshot_info *snap= info.m_snap[n];
@@ -1395,7 +1458,7 @@ int restore_table_data(THD *thd, Restore
res= snap->get_restore_driver(drv[n]);
if (res == backup::ERROR)
{
- info.m_ctx.fatal_error(ER_BACKUP_CREATE_RESTORE_DRIVER, snap->name());
+ log.report_error(ER_BACKUP_CREATE_RESTORE_DRIVER, snap->name());
goto error;
};
}
@@ -1406,9 +1469,11 @@ int restore_table_data(THD *thd, Restore
res= drv[n]->begin(0);
if (res == backup::ERROR)
{
- info.m_ctx.fatal_error(ER_BACKUP_INIT_RESTORE_DRIVER, info.m_snap[n]->name());
+ log.report_error(ER_BACKUP_INIT_RESTORE_DRIVER, info.m_snap[n]->name());
goto error;
}
+
+ active[n]= drv[n];
}
DEBUG_SYNC(thd, "restore_in_progress");
@@ -1426,8 +1491,6 @@ int restore_table_data(THD *thd, Restore
// main data reading loop
- st_bstream_data_chunk chunk_info;
-
while ( state != DONE && state != ERROR )
{
switch (state) {
@@ -1449,9 +1512,8 @@ int restore_table_data(THD *thd, Restore
break;
case BSTREAM_ERROR:
- info.m_ctx.fatal_error(ER_BACKUP_READ_DATA);
+ log.report_error(ER_BACKUP_READ_DATA);
default:
- state= ERROR;
goto error;
}
@@ -1491,7 +1553,8 @@ int restore_table_data(THD *thd, Restore
*/
DBUG_ASSERT(snap && drvr);
- switch( drvr->send_data(buf) ) {
+ ret= drvr->send_data(buf);
+ switch (ret) {
case backup::OK:
info.data_size += buf.size;
@@ -1504,8 +1567,13 @@ int restore_table_data(THD *thd, Restore
case backup::ERROR:
if( errors > MAX_ERRORS )
{
- info.m_ctx.fatal_error(ER_BACKUP_SEND_DATA, buf.table_num, snap->name());
- state= ERROR;
+ log.report_error(ER_BACKUP_SEND_DATA, buf.table_num, snap->name());
+ /*
+ If driver signals error then it is not active any longer - neither
+ ->end() nor ->cancel() should be called on it, only ->free().
+ This is why we need to remove it from active[] array.
+ */
+ active[snap_num]= NULL;
goto error;
}
errors++;
@@ -1516,8 +1584,7 @@ int restore_table_data(THD *thd, Restore
default:
if( repeats > MAX_REPEATS )
{
- info.m_ctx.fatal_error(ER_BACKUP_SEND_DATA_RETRY, repeats, snap->name());
- state= ERROR;
+ log.report_error(ER_BACKUP_SEND_DATA_RETRY, repeats, snap->name());
goto error;
}
repeats++;
@@ -1526,7 +1593,7 @@ int restore_table_data(THD *thd, Restore
default:
break;
- } // switch(state)
+ } // switch(ret)
} // main reading loop
@@ -1536,49 +1603,69 @@ int restore_table_data(THD *thd, Restore
}
DEBUG_SYNC(::current_thd, "restore_table_data_before_end");
-
- { // Shutting down drivers
- String bad_drivers;
+ // Call end() for all active drivers.
- for (uint n=0; n < info.snap_count(); ++n)
- {
- if (!drv[n])
- continue;
+ for (uint n=0; n < info.snap_count(); ++n)
+ {
+ if (!active[n])
+ continue;
- DBUG_PRINT("restore",("Shutting down restore driver %s",
- info.m_snap[n]->name()));
- res= drv[n]->end();
- if (res == backup::ERROR)
- {
- state= ERROR;
+ DBUG_PRINT("restore",("Shutting down restore driver %s",
+ info.m_snap[n]->name()));
+ res= active[n]->end();
+ if (res == backup::ERROR)
+ {
+ state= ERROR;
- if (!bad_drivers.is_empty())
- bad_drivers.append(",");
- bad_drivers.append(info.m_snap[n]->name());
- }
- drv[n]->free(); // Never errors
+ if (!bad_drivers.is_empty())
+ bad_drivers.append(",");
+ bad_drivers.append(info.m_snap[n]->name());
}
-
- if (!bad_drivers.is_empty())
- info.m_ctx.report_error(ER_BACKUP_STOP_RESTORE_DRIVERS, bad_drivers.c_ptr());
}
- DBUG_RETURN(state == ERROR ? backup::ERROR : 0);
+ goto finish;
- error:
+error:
+
+ state= ERROR;
DBUG_PRINT("restore",("Cancelling restore process"));
+ // Call cancel() for all active drivers
+
for (uint n=0; n < info.snap_count(); ++n)
{
- if (!drv[n])
+ if (!active[n])
continue;
+ DBUG_PRINT("restore",("Cancelling restore driver %s",
+ info.m_snap[n]->name()));
+ res= active[n]->cancel();
+
+ if (res)
+ {
+ if (!bad_drivers.is_empty())
+ bad_drivers.append(",");
+ bad_drivers.append(info.m_snap[n]->name());
+ }
+ }
+
+finish:
+
+ if (!bad_drivers.is_empty())
+ log.report_error(ER_BACKUP_STOP_RESTORE_DRIVERS, bad_drivers.c_ptr());
+
+ // Call free() for all existing drivers
+
+ for (uint n=0; n < info.snap_count(); ++n)
+ {
+ if (!drv[n])
+ continue;
drv[n]->free(); // Never errors
}
- DBUG_RETURN(backup::ERROR);
+ DBUG_RETURN(state == ERROR ? backup::ERROR : 0);
}
=== modified file 'sql/backup/image_info.cc'
--- a/sql/backup/image_info.cc 2008-11-05 09:41:15 +0000
+++ b/sql/backup/image_info.cc 2008-11-26 10:05:19 +0000
@@ -1,4 +1,5 @@
#include "../mysql_priv.h"
+#include "../rpl_mi.h"
#include "image_info.h"
#include "be_native.h"
@@ -50,6 +51,7 @@ Image_info::Image_info()
#endif
bzero(m_snap, sizeof(m_snap));
+ bzero(&master_pos, sizeof(master_pos));
}
Image_info::~Image_info()
@@ -169,8 +171,7 @@ int Image_info::add_snapshot(Snapshot_in
{
uint num= st_bstream_image_header::snap_count++;
- // The limit of 256 snapshots is imposed by backup stream format.
- if (num > 256)
+ if (num > MAX_SNAP_COUNT)
return -1;
m_snap[num]= &snap;
@@ -384,6 +385,14 @@ Image_info::Obj *find_obj(const Image_in
}
}
+void Image_info::save_master_pos(const ::Master_info &mi)
+{
+ // store binlog coordinates
+ master_pos.pos= static_cast<unsigned long int>(mi.master_log_pos);
+ master_pos.file= const_cast<char*>(mi.master_log_name);
+}
+
+
} // backup namespace
template class Map<uint, backup::Image_info::Db>;
=== modified file 'sql/backup/image_info.h'
--- a/sql/backup/image_info.h 2008-11-05 09:41:15 +0000
+++ b/sql/backup/image_info.h 2008-11-26 10:05:19 +0000
@@ -10,6 +10,16 @@
#include <backup_stream.h> // for st_bstream_* types
#include <backup/backup_aux.h> // for Map template
+/**
+ @brief The maximal number of table data snapshots per backup image.
+
+ @note This limit is determined by the backup image format used and can
+ not be changed. Currently we use version 1 of the image format in which
+ one byte is used to store snapshot numbers, hence the limit is 256.
+*/
+#define MAX_SNAP_COUNT 256
+
+
class Backup_restore_ctx;
namespace backup {
@@ -75,6 +85,7 @@ public: // public interface
// info about image (most of it is in the st_bstream_image_header base
size_t data_size; ///< How much of table data is saved in the image.
+ st_bstream_binlog_pos master_pos; ///< To store master position info.
ulong table_count() const;
uint db_count() const;
@@ -101,12 +112,8 @@ public: // public interface
/**
Pointers to @c Snapshot_info objects corresponding to the snapshots
present in the image.
-
- We can have at most 256 different snapshots which is a limitation imposed
- by the backup stream library (the number of snapshots is stored inside
- backup image using one byte field).
*/
- Snapshot_info *m_snap[256];
+ Snapshot_info *m_snap[MAX_SNAP_COUNT];
// save timing & binlog info
@@ -115,6 +122,7 @@ public: // public interface
void save_vp_time(const time_t time);
void save_binlog_pos(const ::LOG_INFO&);
+ void save_master_pos(const ::Master_info&);
time_t get_vp_time() const;
=== modified file 'sql/backup/kernel.cc'
--- a/sql/backup/kernel.cc 2008-11-20 13:53:41 +0000
+++ b/sql/backup/kernel.cc 2008-11-25 17:44:19 +0000
@@ -156,11 +156,8 @@ execute_backup_command(THD *thd, LEX *le
folders in the path could have been moved, deleted, etc.
*/
if (backupdir->length() && my_access(backupdir->c_ptr(), (F_OK|W_OK)))
- {
- context.fatal_error(ER_BACKUP_BACKUPDIR, backupdir->c_ptr());
DBUG_RETURN(send_error(context, ER_BACKUP_BACKUPDIR, backupdir->c_ptr()));
- }
-
+
switch (lex->sql_command) {
case SQLCOM_BACKUP:
@@ -197,7 +194,7 @@ execute_backup_command(THD *thd, LEX *le
if (info->db_count() == 0)
{
- context.fatal_error(ER_BACKUP_NOTHING_TO_BACKUP);
+ context.report_error(ER_BACKUP_NOTHING_TO_BACKUP);
DBUG_RETURN(send_error(context, ER_BACKUP_NOTHING_TO_BACKUP));
}
@@ -256,23 +253,21 @@ execute_backup_command(THD *thd, LEX *le
}
/**
- Report errors.
+ Sends error notification after failed backup/restore operation.
- Current implementation reports the last error saved in the logger if it exist.
- Otherwise it reports error given by @c error_code.
+ @param[in] ctx The context of the backup/restore operation.
+ @param[in] error_code Error to be reported if no errors reported yet.
- @returns 0 on success, error code otherwise.
- */
-int send_error(Backup_restore_ctx &log, int error_code, ...)
+ If an error has been already reported then nothing is done - the first
+ logged error will be send to the client. Otherwise, if no errors were
+ reported yet, the given error is sent to the client (but not reported).
+
+ @returns The error code given as argument.
+*/
+static
+int send_error(Backup_restore_ctx &context, int error_code, ...)
{
- util::SAVED_MYSQL_ERROR *error= log.last_saved_error();
-
- if (error && !util::report_mysql_error(log.thd(), error, error_code))
- {
- if (error->code)
- error_code= error->code;
- }
- else // there are no error information in the logger - report error_code
+ if (!context.error_reported())
{
char buf[ERRMSGSIZE + 20];
va_list args;
@@ -284,8 +279,8 @@ int send_error(Backup_restore_ctx &log,
va_end(args);
}
- if (log.backup::Logger::m_state == backup::Logger::RUNNING)
- log.report_stop(my_time(0), FALSE); // FASLE = no success
+ if (context.backup::Logger::m_state == backup::Logger::RUNNING)
+ context.report_stop(my_time(0), FALSE); // FASLE = no success
return error_code;
}
@@ -296,6 +291,8 @@ int send_error(Backup_restore_ctx &log,
Currently the id of the operation is returned to the client. It can
be used to select correct entries from the backup progress tables.
+ @note If an error has been reported, send_error() is invoked instead.
+
@returns 0 on success, error code otherwise.
*/
int send_reply(Backup_restore_ctx &context)
@@ -306,6 +303,9 @@ int send_reply(Backup_restore_ctx &conte
DBUG_ENTER("send_reply");
+ if (context.error_reported())
+ return send_error(context, ER_UNKNOWN_ERROR);
+
/*
Send field list.
*/
@@ -336,9 +336,9 @@ int send_reply(Backup_restore_ctx &conte
DBUG_RETURN(0);
err:
- DBUG_RETURN(context.fatal_error(ER_BACKUP_SEND_REPLY,
- context.m_type == backup::Logger::BACKUP
- ? "BACKUP" : "RESTORE"));
+ DBUG_RETURN(context.report_error(ER_BACKUP_SEND_REPLY,
+ context.m_type == backup::Logger::BACKUP
+ ? "BACKUP" : "RESTORE"));
}
@@ -497,22 +497,17 @@ int Backup_restore_ctx::prepare(String *
if (m_error)
return m_error;
- // Prepare error reporting context.
-
- mysql_reset_errors(m_thd, 0); // Never errors
- m_thd->no_warnings_for_error= FALSE;
-
- save_errors(); // Never errors
-
+ int ret= 0;
/*
Check access for SUPER rights. If user does not have SUPER, fail with error.
+
+ In case of error, we write only to backup logs, because check_global_access()
+ pushes the same error on the error stack.
*/
- if (check_global_access(m_thd, SUPER_ACL))
- {
- fatal_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, "SUPER");
- return m_error;
- }
+ ret= check_global_access(m_thd, SUPER_ACL);
+ if (ret)
+ return fatal_error(log_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, "SUPER"));
/*
Check if another BACKUP/RESTORE is running and if not, register
@@ -529,7 +524,10 @@ int Backup_restore_ctx::prepare(String *
pthread_mutex_unlock(&run_lock);
if (m_error)
+ {
+ report_error(ER_BACKUP_RUNNING);
return m_error;
+ }
// check if location is valid (we assume it is a file path)
@@ -551,10 +549,7 @@ int Backup_restore_ctx::prepare(String *
#endif
if (bad_filename)
- {
- fatal_error(ER_BAD_PATH, location.str);
- return m_error;
- }
+ return fatal_error(report_error(ER_BAD_PATH, location.str));
/*
Computer full path to backup file.
@@ -569,18 +564,13 @@ int Backup_restore_ctx::prepare(String *
mem_alloc= new Mem_allocator();
if (!mem_alloc)
- {
- fatal_error(ER_OUT_OF_RESOURCES);
- return m_error;
- }
+ return fatal_error(report_error(ER_OUT_OF_RESOURCES));
// Freeze all meta-data.
- if (obs::ddl_blocker_enable(m_thd))
- {
- fatal_error(ER_DDL_BLOCK);
- return m_error;
- }
+ ret= obs::ddl_blocker_enable(m_thd);
+ if (ret)
+ return fatal_error(report_error(ER_DDL_BLOCK));
return 0;
}
@@ -614,7 +604,7 @@ Backup_restore_ctx::prepare_for_backup(S
if (m_error)
return NULL;
- if (Logger::init(BACKUP, query))
+ if (Logger::init(BACKUP, query)) // Logs errors
{
fatal_error(ER_BACKUP_LOGGER_INIT);
return NULL;
@@ -640,10 +630,13 @@ Backup_restore_ctx::prepare_for_backup(S
if (!s)
{
- fatal_error(ER_OUT_OF_RESOURCES);
+ fatal_error(report_error(ER_OUT_OF_RESOURCES));
return NULL;
}
-
+
+ // Mark that the file should be removed unless operation completes successfuly
+ m_remove_loc= TRUE;
+
int my_open_status= s->open();
if (my_open_status != 0)
{
@@ -655,16 +648,20 @@ Backup_restore_ctx::prepare_for_backup(S
Create backup catalogue.
*/
- Backup_info *info= new Backup_info(*this); // Logs errors
+ Backup_info *info= new Backup_info(*this, m_thd); // Logs errors
if (!info)
{
- fatal_error(ER_OUT_OF_RESOURCES);
+ fatal_error(report_error(ER_OUT_OF_RESOURCES));
return NULL;
}
if (!info->is_valid())
- return NULL; // Error has been logged by Backup_Info constructor
+ {
+ // Error has been logged by Backup_info constructor
+ fatal_error(ER_BACKUP_BACKUP_PREPARE);
+ return NULL;
+ }
/*
If binlog is enabled, set BSTREAM_FLAG_BINLOG in the header to indicate
@@ -735,7 +732,7 @@ Backup_restore_ctx::prepare_for_restore(
if (!s)
{
- fatal_error(ER_OUT_OF_RESOURCES);
+ fatal_error(report_error(ER_OUT_OF_RESOURCES));
return NULL;
}
@@ -750,45 +747,57 @@ Backup_restore_ctx::prepare_for_restore(
Create restore catalogue.
*/
- Restore_info *info= new Restore_info(*this); // reports errors
+ Restore_info *info= new Restore_info(*this, m_thd); // reports errors
if (!info)
{
- fatal_error(ER_OUT_OF_RESOURCES);
+ fatal_error(report_error(ER_OUT_OF_RESOURCES));
return NULL;
}
if (!info->is_valid())
+ {
+ // Errors are logged by Restore_info constructor.
+ fatal_error(ER_BACKUP_RESTORE_PREPARE);
return NULL;
+ }
info->save_start_time(when);
m_catalog= info;
+ int ret;
+
/*
- Read catalogue from the input stream.
+ Read header and catalogue from the input stream.
*/
- if (read_header(*info, *s))
+ ret= read_header(*info, *s); // Can log errors via callback functions.
+ if (ret)
{
- fatal_error(ER_BACKUP_READ_HEADER);
+ if (!error_reported())
+ report_error(ER_BACKUP_READ_HEADER);
+ fatal_error(ret);
return NULL;
}
if (s->next_chunk() != BSTREAM_OK)
{
- fatal_error(ER_BACKUP_NEXT_CHUNK);
+ fatal_error(report_error(ER_BACKUP_NEXT_CHUNK));
return NULL;
}
- if (read_catalog(*info, *s))
+ ret= read_catalog(*info, *s); // Can log errors via callback functions.
+ if (ret)
{
- fatal_error(ER_BACKUP_READ_HEADER);
+ if (!error_reported())
+ report_error(ER_BACKUP_READ_HEADER);
+ fatal_error(ret);
return NULL;
}
if (s->next_chunk() != BSTREAM_OK)
{
- fatal_error(ER_BACKUP_NEXT_CHUNK);
+ fatal_error(report_error(ER_BACKUP_NEXT_CHUNK));
return NULL;
}
@@ -835,6 +844,7 @@ Backup_restore_ctx::prepare_for_restore(
int Backup_restore_ctx::lock_tables_for_restore()
{
TABLE_LIST *tables= NULL;
+ int ret;
/*
Iterate over all tables in all snapshots and create a linked TABLE_LIST
@@ -855,7 +865,7 @@ int Backup_restore_ctx::lock_tables_for_
if (!ptr)
{
// Error has been reported, but not logged to backup logs
- return log_error(ER_OUT_OF_RESOURCES);
+ return fatal_error(log_error(ER_OUT_OF_RESOURCES));
}
tables= backup::link_table_list(*ptr, tables); // Never errors
@@ -872,16 +882,13 @@ int Backup_restore_ctx::lock_tables_for_
Note 2: Skiping tmp tables is also important because otherwise a tmp table
can occlude a regular table with the same name (BUG#33574).
*/
- if (open_and_lock_tables_derived(m_thd, tables,
- FALSE, /* do not process derived tables */
- MYSQL_OPEN_SKIP_TEMPORARY
+ ret= open_and_lock_tables_derived(m_thd, tables,
+ FALSE, /* do not process derived tables */
+ MYSQL_OPEN_SKIP_TEMPORARY
/* do not open tmp tables */
- )
- )
- {
- fatal_error(ER_BACKUP_OPEN_TABLES,"RESTORE");
- return m_error;
- }
+ );
+ if (ret)
+ return fatal_error(report_error(ER_BACKUP_OPEN_TABLES,"RESTORE"));
m_tables_locked= TRUE;
return 0;
@@ -906,39 +913,6 @@ void Backup_restore_ctx::unlock_tables()
/**
- Report error and move context object into error state without pushing the
- error on the server's warning stack.
-
- Similar to @c fatal_error, but does not push the error on the
- server's warning stack. To be used when an error is reported from a
- server function that has already pushed the error on the warning stack.
-
- @return error code given as input or stored in the context object if
- a fatal error was reported before.
- */
-inline
-int Backup_restore_ctx::log_error(int error_code, ...)
-{
- if (m_error)
- return m_error;
-
- bool saved = push_errors(FALSE); // Do not use warning stack
-
- m_error= error_code;
- m_remove_loc= TRUE;
-
- va_list args;
- va_start(args,error_code);
- v_report_error(backup::log_level::ERROR, error_code, args);
- va_end(args);
-
- push_errors(saved); // Reset
-
- return error_code;
-}
-
-
-/**
Destroy a backup/restore context.
This should reverse all settings made when context was created and prepared.
@@ -952,7 +926,6 @@ int Backup_restore_ctx::log_error(int er
*/
int Backup_restore_ctx::close()
{
- int error= 0;
if (m_state == CLOSED)
return 0;
@@ -986,7 +959,7 @@ int Backup_restore_ctx::close()
if (m_stream && !m_stream->close())
{
// Note error, but complete clean-up
- error= ER_BACKUP_CLOSE;
+ fatal_error(report_error(ER_BACKUP_CLOSE));
}
if (m_catalog)
@@ -1000,31 +973,25 @@ int Backup_restore_ctx::close()
*/
if (m_remove_loc && m_state == PREPARED_FOR_BACKUP)
{
- int res= my_delete(m_path.c_ptr(), MYF(0));
+ int ret= my_delete(m_path.c_ptr(), MYF(0));
/*
Ignore ENOENT error since it is ok if the file doesn't exist.
*/
- if (res && my_errno != ENOENT)
- {
- error= ER_CANT_DELETE_FILE;
- }
+ if (ret && my_errno != ENOENT)
+ fatal_error(report_error(ER_CANT_DELETE_FILE, m_path.c_ptr(), my_errno));
}
/* We report completion of the operation only if no errors were detected,
and logger has been initialized.
*/
- if (!error)
+ if (!m_error)
{
if (backup::Logger::m_state == backup::Logger::RUNNING)
{
report_stop(when, TRUE);
}
}
- else
- {
- fatal_error(error); // Log error
- }
/*
Destroy backup stream's memory allocator (this frees memory)
@@ -1045,7 +1012,7 @@ int Backup_restore_ctx::close()
pthread_mutex_unlock(&run_lock);
m_state= CLOSED;
- return error;
+ return m_error;
}
/**
@@ -1068,6 +1035,7 @@ int Backup_restore_ctx::do_backup()
using namespace backup;
+ int ret;
Output_stream &s= *static_cast<Output_stream*>(m_stream);
Backup_info &info= *static_cast<Backup_info*>(m_catalog);
@@ -1078,27 +1046,33 @@ int Backup_restore_ctx::do_backup()
DBUG_PRINT("backup",("Writing preamble"));
DEBUG_SYNC(m_thd, "backup_before_write_preamble");
- if (write_preamble(info, s))
+ ret= write_preamble(info, s); // Can Log errors via callback functions.
+ if (ret)
{
- fatal_error(ER_BACKUP_WRITE_HEADER);
- DBUG_RETURN(m_error);
+ if (!error_reported())
+ report_error(ER_BACKUP_WRITE_HEADER);
+ DBUG_RETURN(fatal_error(ret));
}
DBUG_PRINT("backup",("Writing table data"));
DEBUG_SYNC(m_thd, "before_backup_data");
- if (write_table_data(m_thd, info, s)) // logs errors
- DBUG_RETURN(send_error(*this, ER_BACKUP_BACKUP));
+ ret= write_table_data(m_thd, info, s); // logs errors
+ if (ret)
+ DBUG_RETURN(fatal_error(ret));
DBUG_PRINT("backup",("Writing summary"));
- if (write_summary(info, s))
- {
- fatal_error(ER_BACKUP_WRITE_SUMMARY);
- DBUG_RETURN(m_error);
- }
+ ret= write_summary(info, s);
+ if (ret)
+ DBUG_RETURN(fatal_error(report_error(ER_BACKUP_WRITE_SUMMARY)));
+ /*
+ Now backup image has been written. Set m_remove_loc to FALSE, so that the
+ backup file is not removed in Backup_restore_ctx::close().
+ */
+ m_remove_loc= FALSE;
report_stats_post(info); // Never errors
DBUG_PRINT("backup",("Backup done."));
@@ -1135,9 +1109,7 @@ int Backup_restore_ctx::restore_triggers
Image_info::Iterator *dbit= m_catalog->get_dbs();
if (!dbit)
- {
- DBUG_RETURN(fatal_error(ER_OUT_OF_RESOURCES));
- }
+ DBUG_RETURN(fatal_error(report_error(ER_OUT_OF_RESOURCES)));
// create all trigers and collect events in the events list
@@ -1146,9 +1118,8 @@ int Backup_restore_ctx::restore_triggers
Image_info::Iterator *it=
m_catalog->get_db_objects(*static_cast<Image_info::Db*>(obj));
if (!it)
- {
- DBUG_RETURN(fatal_error(ER_OUT_OF_RESOURCES));
- }
+ DBUG_RETURN(fatal_error(report_error(ER_OUT_OF_RESOURCES)));
+
while ((obj= (*it)++))
switch (obj->type()) {
@@ -1157,7 +1128,7 @@ int Backup_restore_ctx::restore_triggers
if (events.push_back(obj))
{
// Error has been reported, but not logged to backup logs
- DBUG_RETURN(log_error(ER_OUT_OF_RESOURCES));
+ DBUG_RETURN(fatal_error(log_error(ER_OUT_OF_RESOURCES)));
}
break;
@@ -1167,8 +1138,9 @@ int Backup_restore_ctx::restore_triggers
{
delete it;
delete dbit;
- fatal_error(ER_BACKUP_CANT_RESTORE_TRIGGER,obj->describe(buf));
- DBUG_RETURN(m_error);
+ int err= report_error(ER_BACKUP_CANT_RESTORE_TRIGGER,
+ obj->describe(buf));
+ DBUG_RETURN(fatal_error(err));
}
break;
@@ -1188,8 +1160,8 @@ int Backup_restore_ctx::restore_triggers
while ((ev= it++))
if (ev->m_obj_ptr->execute(m_thd))
{
- fatal_error(ER_BACKUP_CANT_RESTORE_EVENT,ev->describe(buf));
- DBUG_RETURN(m_error);
+ int ret= report_error(ER_BACKUP_CANT_RESTORE_EVENT,ev->describe(buf));
+ DBUG_RETURN(fatal_error(ret));
};
DBUG_RETURN(0);
@@ -1228,18 +1200,21 @@ int Backup_restore_ctx::do_restore(bool
DBUG_PRINT("restore", ("Restoring meta-data"));
// unless RESTORE... OVERWRITE: return error if database already exists
- if (!overwrite) {
+ if (!overwrite)
+ {
Image_info::Db_iterator *dbit= info.get_dbs();
- if (!dbit) {
- DBUG_RETURN(fatal_error(ER_OUT_OF_RESOURCES));
- }
+ if (!dbit)
+ DBUG_RETURN(fatal_error(report_error(ER_OUT_OF_RESOURCES)));
Image_info::Db *mydb;
- while ((mydb= static_cast<Image_info::Db*>((*dbit)++))) {
- if (!obs::check_db_existence(&mydb->name())) {
+ while ((mydb= static_cast<Image_info::Db*>((*dbit)++)))
+ {
+ if (!obs::check_db_existence(&mydb->name()))
+ {
delete dbit;
- DBUG_RETURN(fatal_error(ER_RESTORE_DB_EXISTS, mydb->name().ptr()));
+ err= report_error(ER_RESTORE_DB_EXISTS, mydb->name().ptr());
+ DBUG_RETURN(fatal_error(err));
}
}
delete dbit;
@@ -1247,17 +1222,17 @@ int Backup_restore_ctx::do_restore(bool
disable_fkey_constraints(); // Never errors
- if (read_meta_data(info, s))
+ err= read_meta_data(info, s); // Can log errors via callback functions.
+ if (err)
{
- m_thd->main_da.reset_diagnostics_area(); // Never errors
-
- fatal_error(ER_BACKUP_READ_META);
- DBUG_RETURN(m_error);
+ if (!error_reported())
+ report_error(ER_BACKUP_READ_META);
+ DBUG_RETURN(fatal_error(err));
}
if (s.next_chunk() == BSTREAM_ERROR)
{
- DBUG_RETURN(fatal_error(ER_BACKUP_NEXT_CHUNK));
+ DBUG_RETURN(fatal_error(report_error(ER_BACKUP_NEXT_CHUNK)));
}
DBUG_PRINT("restore",("Restoring table data"));
@@ -1271,16 +1246,17 @@ int Backup_restore_ctx::do_restore(bool
close_thread_tables(m_thd); // Never errors
m_thd->main_da.reset_diagnostics_area(); // Never errors
- if (lock_tables_for_restore()) // logs errors
- DBUG_RETURN(m_error);
+ err= lock_tables_for_restore(); // logs errors
+ if (err)
+ DBUG_RETURN(fatal_error(err));
// Here restore drivers are created to restore table data
- err= restore_table_data(m_thd, info, s); // reports errors
+ err= restore_table_data(m_thd, info, s); // logs errors
unlock_tables(); // Never errors
if (err)
- DBUG_RETURN(ER_BACKUP_RESTORE);
+ DBUG_RETURN(fatal_error(err));
/*
Re-create all triggers and events (it was not done in @c bcat_create_item()).
@@ -1289,16 +1265,9 @@ int Backup_restore_ctx::do_restore(bool
creation of these objects will fail.
*/
- if (restore_triggers_and_events()) // reports errors
- DBUG_RETURN(ER_BACKUP_RESTORE);
-
- DBUG_PRINT("restore",("Done."));
-
- if (read_summary(info, s))
- {
- fatal_error(ER_BACKUP_READ_SUMMARY);
- DBUG_RETURN(m_error);
- }
+ err= restore_triggers_and_events(); // logs errors
+ if (err)
+ DBUG_RETURN(fatal_error(err));
/*
FIXME: this call is here because object services doesn't clean the
@@ -1309,6 +1278,12 @@ int Backup_restore_ctx::do_restore(bool
close_thread_tables(m_thd); // Never errors
m_thd->main_da.reset_diagnostics_area(); // Never errors
+ DBUG_PRINT("restore",("Done."));
+
+ err= read_summary(info, s);
+ if (err)
+ DBUG_RETURN(fatal_error(report_error(ER_BACKUP_READ_SUMMARY)));
+
/*
Report validity point time and binlog position stored in the backup image
(in the summary section).
@@ -1326,8 +1301,7 @@ int Backup_restore_ctx::do_restore(bool
}
/**
- Report stream open error by calling fatal_error, effectively moving
- context object into error state.
+ Report stream open error and move context object into error state.
@return error code given as input or the one stored in the context
object if a fatal error has already been reported.
@@ -1338,26 +1312,26 @@ int Backup_restore_ctx::report_stream_op
int error= 0;
switch (my_open_status) {
case ER_OPTION_PREVENTS_STATEMENT:
- error= fatal_error(ER_OPTION_PREVENTS_STATEMENT, "--secure-file-priv");
+ error= report_error(ER_OPTION_PREVENTS_STATEMENT, "--secure-file-priv");
break;
case ER_BACKUP_WRITE_LOC:
/*
For this error, use the actual value returned instead of the
path complimented with backupdir.
*/
- error= fatal_error(ER_BACKUP_WRITE_LOC, location->str);
+ error= report_error(ER_BACKUP_WRITE_LOC, location->str);
break;
case ER_BACKUP_READ_LOC:
/*
For this error, use the actual value returned instead of the
path complimented with backupdir.
*/
- error= fatal_error(ER_BACKUP_READ_LOC, location->str);
+ error= report_error(ER_BACKUP_READ_LOC, location->str);
break;
default:
DBUG_ASSERT(FALSE);
}
- return error;
+ return fatal_error(error);
}
namespace backup {
@@ -1502,6 +1476,7 @@ int bcat_reset(st_bstream_image_header *
DBUG_ASSERT(catalogue);
Restore_info *info= static_cast<Restore_info*>(catalogue);
+ Logger &log= info->m_log;
/*
Iterate over the list of snapshots read from the backup image (and stored
@@ -1526,50 +1501,50 @@ int bcat_reset(st_bstream_image_header *
if (!se || !hton)
{
- info->m_ctx.fatal_error(ER_BACKUP_CANT_FIND_SE, name_lex.str);
+ log.report_error(ER_BACKUP_CANT_FIND_SE, name_lex.str);
return BSTREAM_ERROR;
}
if (!hton->get_backup_engine)
{
- info->m_ctx.fatal_error(ER_BACKUP_NO_NATIVE_BE, name_lex.str);
+ log.report_error(ER_BACKUP_NO_NATIVE_BE, name_lex.str);
return BSTREAM_ERROR;
}
- info->m_snap[n]= new Native_snapshot(info->m_ctx, snap->version, se);
+ info->m_snap[n]= new Native_snapshot(log, snap->version, se);
// reports errors
break;
}
case BI_NODATA:
- info->m_snap[n]= new Nodata_snapshot(info->m_ctx, snap->version);
+ info->m_snap[n]= new Nodata_snapshot(log, snap->version);
// reports errors
break;
case BI_CS:
- info->m_snap[n]= new CS_snapshot(info->m_ctx, snap->version);
+ info->m_snap[n]= new CS_snapshot(log, snap->version);
// reports errors
break;
case BI_DEFAULT:
- info->m_snap[n]= new Default_snapshot(info->m_ctx, snap->version);
+ info->m_snap[n]= new Default_snapshot(log, snap->version);
// reports errors
break;
default:
// note: we use convention that snapshots are counted starting from 1.
- info->m_ctx.fatal_error(ER_BACKUP_UNKNOWN_BE, n + 1);
+ log.report_error(ER_BACKUP_UNKNOWN_BE, n + 1);
return BSTREAM_ERROR;
}
if (!info->m_snap[n])
{
- info->m_ctx.fatal_error(ER_OUT_OF_RESOURCES);
+ log.report_error(ER_OUT_OF_RESOURCES);
return BSTREAM_ERROR;
}
info->m_snap[n]->m_num= n + 1;
- info->m_ctx.report_driver(info->m_snap[n]->name());
+ log.report_driver(info->m_snap[n]->name());
}
return BSTREAM_OK;
@@ -1599,6 +1574,7 @@ int bcat_add_item(st_bstream_image_heade
using namespace backup;
Restore_info *info= static_cast<Restore_info*>(catalogue);
+ Logger &log= info->m_log;
backup::String name_str(item->name.begin, item->name.end);
@@ -1639,7 +1615,7 @@ int bcat_add_item(st_bstream_image_heade
with error earlier.
*/
DBUG_ASSERT(it->snap_num >= info->snap_count());
- info->m_ctx.fatal_error(ER_BACKUP_WRONG_TABLE_BE, it->snap_num + 1);
+ log.report_error(ER_BACKUP_WRONG_TABLE_BE, it->snap_num + 1);
return BSTREAM_ERROR;
}
@@ -1703,6 +1679,7 @@ void* bcat_iterator_get(st_bstream_image
DBUG_ASSERT(catalogue);
Backup_info *info= static_cast<Backup_info*>(catalogue);
+ backup::Logger &log= info->m_log;
switch (type) {
@@ -1721,7 +1698,7 @@ void* bcat_iterator_get(st_bstream_image
Iterator *it= info->get_tablespaces();
if (!it)
{
- info->m_ctx.fatal_error(ER_OUT_OF_RESOURCES);
+ log.report_error(ER_OUT_OF_RESOURCES);
return NULL;
}
@@ -1733,7 +1710,7 @@ void* bcat_iterator_get(st_bstream_image
Iterator *it= info->get_dbs();
if (!it)
{
- info->m_ctx.fatal_error(ER_OUT_OF_RESOURCES);
+ log.report_error(ER_OUT_OF_RESOURCES);
return NULL;
}
@@ -1746,7 +1723,7 @@ void* bcat_iterator_get(st_bstream_image
if (!it)
{
- info->m_ctx.fatal_error(ER_BACKUP_CAT_ENUM);
+ log.report_error(ER_BACKUP_CAT_ENUM);
return NULL;
}
@@ -1837,18 +1814,19 @@ void* bcat_db_iterator_get(st_bstream_im
DBUG_ASSERT(dbi);
Backup_info *info= static_cast<Backup_info*>(catalogue);
+ backup::Logger &log= info->m_log;
Backup_info::Db *db = info->get_db(dbi->base.pos);
if (!db)
{
- info->m_ctx.fatal_error(ER_BACKUP_UNKNOWN_OBJECT);
+ log.report_error(ER_BACKUP_UNKNOWN_OBJECT);
return NULL;
}
backup::Image_info::Iterator *it= info->get_db_objects(*db);
if (!it)
{
- info->m_ctx.fatal_error(ER_OUT_OF_RESOURCES);
+ log.report_error(ER_OUT_OF_RESOURCES);
return NULL;
}
@@ -1901,7 +1879,8 @@ int bcat_create_item(st_bstream_image_he
DBUG_ASSERT(item);
Restore_info *info= static_cast<Restore_info*>(catalogue);
- THD *thd= info->m_ctx.thd();
+ Logger &log= info->m_log;
+ THD *thd= info->m_thd;
int create_err= 0;
switch (item->type) {
@@ -1923,7 +1902,7 @@ int bcat_create_item(st_bstream_image_he
*/
default:
- info->m_ctx.fatal_error(ER_BACKUP_UNKNOWN_OBJECT_TYPE);
+ log.report_error(ER_BACKUP_UNKNOWN_OBJECT_TYPE);
return BSTREAM_ERROR;
}
@@ -1931,7 +1910,7 @@ int bcat_create_item(st_bstream_image_he
if (!obj)
{
- info->m_ctx.fatal_error(ER_BACKUP_UNKNOWN_OBJECT);
+ log.report_error(ER_BACKUP_UNKNOWN_OBJECT);
return BSTREAM_ERROR;
}
@@ -1950,7 +1929,7 @@ int bcat_create_item(st_bstream_image_he
if (!sobj)
{
- info->m_ctx.fatal_error(create_err, desc);
+ log.report_error(create_err, desc);
return BSTREAM_ERROR;
}
@@ -1992,7 +1971,7 @@ int bcat_create_item(st_bstream_image_he
if (ts)
{
DBUG_PRINT("restore",(" tablespace has changed on the server - aborting"));
- info->m_ctx.fatal_error(ER_BACKUP_TS_CHANGE, desc);
+ log.report_error(ER_BACKUP_TS_CHANGE, desc);
delete ts;
return BSTREAM_ERROR;
}
@@ -2015,9 +1994,9 @@ int bcat_create_item(st_bstream_image_he
*/
if (!obs::check_user_existence(thd, sobj->get_name()))
{
- info->m_ctx.report_error(log_level::WARNING,
- ER_BACKUP_GRANT_SKIPPED,
- create_stmt);
+ log.report_error(log_level::WARNING,
+ ER_BACKUP_GRANT_SKIPPED,
+ create_stmt);
return BSTREAM_OK;
}
/*
@@ -2037,14 +2016,14 @@ int bcat_create_item(st_bstream_image_he
db_name.append(start, size);
if (!info->has_db(db_name))
{
- info->m_ctx.fatal_error(ER_BACKUP_GRANT_WRONG_DB, create_stmt);
+ log.report_error(ER_BACKUP_GRANT_WRONG_DB, create_stmt);
return BSTREAM_ERROR;
}
}
if (sobj->execute(thd))
{
- info->m_ctx.fatal_error(create_err, desc);
+ log.report_error(create_err, desc);
return BSTREAM_ERROR;
}
@@ -2115,11 +2094,12 @@ int bcat_get_item_create_query(st_bstrea
::String *buf= &(info->serialization_buf);
buf->length(0);
- if (obj->m_obj_ptr->serialize(info->m_ctx.thd(), buf))
+ if (obj->m_obj_ptr->serialize(info->m_thd, buf))
{
Image_info::Obj::describe_buf dbuf;
- info->m_ctx.fatal_error(meta_err, obj->describe(dbuf));
+ info->m_log.report_error(meta_err, obj->describe(dbuf));
+
return BSTREAM_ERROR;
}
=== modified file 'sql/backup/logger.cc'
--- a/sql/backup/logger.cc 2008-10-27 13:06:21 +0000
+++ b/sql/backup/logger.cc 2008-11-25 17:44:19 +0000
@@ -28,15 +28,27 @@ namespace backup {
the moment. Destinations which are not ready/initialized yet should be
silently ignored.
- @returns 0 on success.
+ @returns Reported error code.
*/
int Logger::write_message(log_level::value level, int error_code,
const char *msg)
{
char buf[ERRMSGSIZE + 30];
+ /*
+ When logging to server's error log, msg will be prefixed with
+ "Backup:"/"Restore:" if the operation has been initialized (i.e., after
+ Logger::init() call). For other destinations, msg is reported as it is.
+
+ Pointer out points at output string for server's error log, which has the
+ prefix added if needed.
+ */
const char *out= msg;
- if (m_state == READY || m_state == RUNNING)
+ /*
+ Note: m_type is meaningful only after a call to init() i.e.,
+ if m_state != CREATED.
+ */
+ if (m_state != CREATED)
{
my_snprintf(buf, sizeof(buf), "%s: %s",
m_type == BACKUP ? "Backup" : "Restore" , msg);
@@ -45,43 +57,61 @@ int Logger::write_message(log_level::val
switch (level) {
case log_level::ERROR:
- if (m_save_errors)
- {
- error.code= error_code;
- error.level= MYSQL_ERROR::WARN_LEVEL_ERROR;
- error.msg= sql_strdup(msg);
- }
+ {
+ // Report to server's error log
sql_print_error(out);
- if (m_push_errors)
- push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- error_code, msg);
- DBUG_PRINT("backup_log",("[ERROR] %s", out));
-
+
+ // Report to the client
+
+ bool saved_value= m_thd->no_warnings_for_error;
+ m_thd->no_warnings_for_error= m_push_errors ? FALSE : TRUE;
+ my_printf_error(error_code, msg, MYF(0));
+ m_thd->no_warnings_for_error= saved_value;
+
+ m_error_reported= TRUE;
+
+ // Report to backup logs
+
if (m_state == READY || m_state == RUNNING)
{
time_t ts = my_time(0);
backup_log->error_num(error_code);
- backup_log->write_progress(0, ts, ts, 0, 0, error_code, out);
+ backup_log->write_progress(0, ts, ts, 0, 0, error_code, msg);
}
- return 0;
+ // Report in the debug trace
+
+ DBUG_PRINT("backup_log",("[ERROR] %s", out));
+
+ return error_code;
+ }
case log_level::WARNING:
+ // Report to server's error log
sql_print_warning(out);
+
+ // Report to the client (push on warning stack)
if (m_push_errors)
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
error_code, msg);
+
+ // Report to the debug trace
DBUG_PRINT("backup_log",("[Warning] %s", out));
- return 0;
+
+ return error_code;
case log_level::INFO:
+ // Report to server's error log
sql_print_information(out);
+
+ // Report to the debug trace
DBUG_PRINT("backup_log",("[Info] %s", out));
- return 0;
- default: return ERROR;
+ return error_code;
+
+ default: DBUG_ASSERT(0); return ERROR;
}
}
@@ -94,7 +124,7 @@ int Logger::write_message(log_level::val
If the message contains placeholders, additional arguments provide
values to be put there.
- @returns 0 on success.
+ @returns Reported error code.
*/
int Logger::v_report_error(log_level::value level, int error_code, va_list args)
{
=== modified file 'sql/backup/logger.h'
--- a/sql/backup/logger.h 2008-11-14 15:02:10 +0000
+++ b/sql/backup/logger.h 2008-11-25 17:44:19 +0000
@@ -51,6 +51,7 @@ class Logger
int report_error(log_level::value level, int error_code, ...);
int report_error(const char *format, ...);
int write_message(log_level::value level, const char *msg, ...);
+ int log_error(int error_code, ...);
void report_start(time_t);
void report_stop(time_t, bool);
@@ -68,11 +69,8 @@ class Logger
return backup_log->get_backup_id();
}
- void save_errors();
- void stop_save_errors();
- void clear_saved_errors();
- util::SAVED_MYSQL_ERROR *last_saved_error();
bool push_errors(bool);
+ bool error_reported() const;
protected:
@@ -84,30 +82,26 @@ class Logger
int write_message(log_level::value level , int error_code, const char *msg);
private:
+
// Prevent copying/assigments
Logger(const Logger&);
Logger& operator=(const Logger&);
- util::SAVED_MYSQL_ERROR error; ///< Used to store saved errors.
- bool m_save_errors; ///< Flag telling if errors should be saved.
bool m_push_errors; ///< Should errors be pushed on warning stack?
+ bool m_error_reported; ///< Has any error been reported?
Backup_log *backup_log; ///< Backup log interface class.
};
inline
Logger::Logger(THD *thd)
- :m_type(BACKUP), m_state(CREATED),
- m_thd(thd), m_save_errors(FALSE), m_push_errors(TRUE), backup_log(0)
-{
- clear_saved_errors();
-}
-
+ :m_type(BACKUP), m_state(CREATED), m_thd(thd), m_push_errors(TRUE),
+ m_error_reported(FALSE), backup_log(0)
+{}
inline
Logger::~Logger()
{
- clear_saved_errors();
delete backup_log;
}
@@ -163,37 +157,20 @@ int Logger::report_error(const char *for
return res;
}
-/// Request that all reported errors are saved in the logger.
-inline
-void Logger::save_errors()
-{
- if (m_save_errors)
- return;
- clear_saved_errors();
- m_save_errors= TRUE;
-}
-
-/// Stop saving errors.
+/// Reports error without pushing it on server's error stack.
inline
-void Logger::stop_save_errors()
+int Logger::log_error(int error_code, ...)
{
- if (!m_save_errors)
- return;
- m_save_errors= FALSE;
-}
+ va_list args;
+ bool saved= push_errors(FALSE);
+
+ va_start(args, error_code);
+ int res= v_report_error(log_level::ERROR, error_code, args);
+ va_end(args);
-/// Delete all saved errors to free resources.
-inline
-void Logger::clear_saved_errors()
-{
- memset(&error, 0, sizeof(error));
-}
+ push_errors(saved);
-/// Return a pointer to most recent saved error.
-inline
-util::SAVED_MYSQL_ERROR *Logger::last_saved_error()
-{
- return error.code ? &error : NULL;
+ return res;
}
/// Report start of an operation.
@@ -328,7 +305,7 @@ void Logger::report_backup_file(char *pa
@returns 0 on success, error code otherwise.
- @todo Decide what to do if @c initialize() signals errors.
+ @todo Detect, log and report errors to the caller.
@todo Add code to get the user comment from command.
*/
inline
@@ -338,13 +315,20 @@ int Logger::init(enum_type type, const c
return 0;
m_type= type;
- m_state= READY;
+ mysql_reset_errors(m_thd, 0); // Never errors
backup_log = new Backup_log(m_thd, (enum_backup_operation)type, query);
backup_log->state(BUP_STARTING);
+ m_state= READY;
DEBUG_SYNC(m_thd, "after_backup_log_init");
return 0;
}
+inline
+bool Logger::error_reported() const
+{
+ return m_error_reported;
+}
+
} // backup namespace
#endif
=== modified file 'sql/backup/restore_info.h'
--- a/sql/backup/restore_info.h 2008-11-13 13:02:36 +0000
+++ b/sql/backup/restore_info.h 2008-11-25 17:44:19 +0000
@@ -33,9 +33,8 @@ class Restore_info: public backup::Image
{
public:
- Backup_restore_ctx &m_ctx;
+ backup::Logger &m_log;
- Restore_info(Backup_restore_ctx&);
~Restore_info();
bool is_valid() const;
@@ -47,19 +46,32 @@ class Restore_info: public backup::Image
private:
+ /*
+ Note: constructor is private because instances of this class are supposed
+ to be created only with Backup_restore_ctx::prepare_for_restore() method.
+ */
+ Restore_info(backup::Logger&, THD*);
+
// Prevent copying/assignments
Restore_info(const Restore_info&);
Restore_info& operator=(const Restore_info&);
+ THD *m_thd;
+
friend int backup::restore_table_data(THD*, Restore_info&,
backup::Input_stream&);
friend int ::bcat_add_item(st_bstream_image_header*,
struct st_bstream_item_info*);
+ friend int ::bcat_create_item(st_bstream_image_header *catalogue,
+ struct st_bstream_item_info *item,
+ bstream_blob create_stmt,
+ bstream_blob other_meta_data);
+ friend class Backup_restore_ctx; // Needs access to the constructor.
};
inline
-Restore_info::Restore_info(Backup_restore_ctx &ctx)
- :m_ctx(ctx)
+Restore_info::Restore_info(backup::Logger &log, THD *thd)
+ :m_log(log), m_thd(thd)
{}
inline
@@ -86,7 +98,7 @@ Restore_info::add_ts(const ::String &nam
Ts *ts= Image_info::add_ts(name, pos);
if (!ts)
- m_ctx.fatal_error(ER_BACKUP_CATALOG_ADD_TS, name.ptr());
+ m_log.report_error(ER_BACKUP_CATALOG_ADD_TS, name.ptr());
return ts;
}
@@ -99,7 +111,7 @@ Restore_info::add_db(const ::String &nam
Db *db= Image_info::add_db(name, pos);
if (!db)
- m_ctx.fatal_error(ER_BACKUP_CATALOG_ADD_DB, name.ptr());
+ m_log.report_error(ER_BACKUP_CATALOG_ADD_DB, name.ptr());
return db;
}
@@ -113,7 +125,7 @@ Restore_info::add_table(Image_info::Db &
Table *t= Image_info::add_table(db, name, snap, pos);
if (!t)
- m_ctx.fatal_error(ER_BACKUP_CATALOG_ADD_TABLE, db.name().ptr(), name.ptr());
+ m_log.report_error(ER_BACKUP_CATALOG_ADD_TABLE, db.name().ptr(), name.ptr());
return t;
}
=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt 2008-11-19 22:08:05 +0000
+++ b/sql/share/errmsg.txt 2008-11-26 10:05:19 +0000
@@ -6436,3 +6436,5 @@ ER_RESTORE_DB_EXISTS
eng "Database \'%-.64s\' already exists. Use OVERWRITE flag to overwrite."
ER_QUERY_CACHE_DISABLED
eng "Query cache is disabled; restart the server with query_cache_type=1 to enable it"
+ER_BACKUP_UNEXPECTED_DATA
+ eng "Backup image contains no tables, but table data was found in it"
=== modified file 'sql/si_logs.h'
--- a/sql/si_logs.h 2008-10-30 17:53:24 +0000
+++ b/sql/si_logs.h 2008-11-14 14:49:09 +0000
@@ -201,7 +201,7 @@ void Backup_log::stop(time_t when)
inline
void Backup_log::binlog_file(char *file)
{
- if (strlen(file) > 0)
+ if (file && strlen(file) > 0)
m_op_hist.binlog_file= file;
}
@@ -217,7 +217,7 @@ void Backup_log::binlog_file(char *file)
inline
void Backup_log::master_binlog_file(char *file)
{
- if (strlen(file) > 0)
+ if (file && strlen(file) > 0)
m_op_hist.master_binlog_file= file;
}
| Thread |
|---|
| • bzr commit into mysql-6.0 branch (jorgen.loland:2729) | Jorgen Loland | 28 Nov |