#At file:///export/home/tmp/oysteing/mysql/mysql-6.0-backup/
2740 Oystein Grovlen 2008-12-17
Bug#39105 Assertion in sql_class.cc when backing up invalid merge table
Assertion no longer happens after new version of object service API
was introduced, but error message could be improved so users are
informed about what is actually wrong. (That base tables are
missing.)
More information is made available by having the service interface
copy its warnings to the THD error stack. Main error message is still
the same, but more information is now found on the error stack.
modified:
mysql-test/lib/mtr_report.pl
mysql-test/suite/backup/r/backup_nodata_driver.result
mysql-test/suite/backup/t/backup_nodata_driver.test
sql/si_objects.cc
per-file messages:
mysql-test/lib/mtr_report.pl
Filter error from added test case that cause backup to fail in
backup.backup_nodata_driver test.
mysql-test/suite/backup/r/backup_nodata_driver.result
Updated result file
mysql-test/suite/backup/t/backup_nodata_driver.test
Add test case for Bug#39105
sql/si_objects.cc
Bug#39105 Assertion in sql_class.cc when backing up invalid merge table
Assertion no longer happens after new version of object service API
was introduced, but error message could be improved so users are
informed about what is actually wrong. (That base tables are
missing.)
More information is made available by having the service interface
copy its warnings to the THD error stack. Main error message is still
the same, but more information is now found on the error stack.
=== modified file 'mysql-test/lib/mtr_report.pl'
=== modified file 'mysql-test/lib/mtr_report.pl'
--- a/mysql-test/lib/mtr_report.pl 2008-11-21 15:02:34 +0000
+++ b/mysql-test/lib/mtr_report.pl 2008-12-17 10:27:06 +0000
@@ -365,6 +365,12 @@
/Restore: Open and lock tables failed in RESTORE/
) or
+ # backup_nodata_driver intentionally provokes an error when backing up MERGE table
+ ($testname eq 'backup.backup_nodata_driver') and
+ (
+ /Backup: Failed to obtain meta-data for table/
+ ) or
+
# The tablespace test triggers error below on purpose
($testname eq 'backup.backup_tablespace') and
(
=== modified file 'mysql-test/suite/backup/r/backup_nodata_driver.result'
--- a/mysql-test/suite/backup/r/backup_nodata_driver.result 2008-11-21 15:02:34 +0000
+++ b/mysql-test/suite/backup/r/backup_nodata_driver.result 2008-12-17 10:27:06 +0000
@@ -308,6 +308,23 @@
SELECT * FROM bup_nodata.e1;
Period Vapor_period
#
+# Test backup of MERGE table whose base tables do not exist. (Bug#39105)
+#
+USE test;
+DROP DATABASE bup_nodata;
+CREATE DATABASE bup_nodata;
+# Create MERGE table where underlying tables t1, t2, does not exist.
+CREATE TABLE bup_nodata.total (A INT NOT NULL AUTO_INCREMENT, MESSAGE CHAR(20), INDEX(A))
+ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
+# Try to back up table. Should get error.
+BACKUP DATABASE bup_nodata TO 'bup_notables.bak';
+ERROR HY000: Failed to obtain meta-data for table `bup_nodata`.`total`
+SHOW WARNINGS;
+Level Code Message
+Error # Table 'test.t1' doesn't exist
+Error # Unable to open underlying table which is differently defined or of non-MyISAM
type or doesn't exist
+Error # Failed to obtain meta-data for table `bup_nodata`.`total`
+#
# Cleanup.
#
DROP DATABASE bup_nodata;
=== modified file 'mysql-test/suite/backup/t/backup_nodata_driver.test'
--- a/mysql-test/suite/backup/t/backup_nodata_driver.test 2008-11-21 15:02:34 +0000
+++ b/mysql-test/suite/backup/t/backup_nodata_driver.test 2008-12-17 10:27:06 +0000
@@ -234,6 +234,26 @@
SELECT * FROM bup_nodata.e1;
--echo #
+--echo # Test backup of MERGE table whose base tables do not exist. (Bug#39105)
+--echo #
+
+# At on point in time the server would crash in the following test
+# if a USE statement was included.
+USE test;
+DROP DATABASE bup_nodata;
+CREATE DATABASE bup_nodata;
+
+--echo # Create MERGE table where underlying tables t1, t2, does not exist.
+CREATE TABLE bup_nodata.total (A INT NOT NULL AUTO_INCREMENT, MESSAGE CHAR(20), INDEX(A))
+ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
+
+--echo # Try to back up table. Should get error.
+--error ER_BACKUP_GET_META_TABLE
+BACKUP DATABASE bup_nodata TO 'bup_notables.bak';
+--replace_column 2 #
+SHOW WARNINGS;
+
+--echo #
--echo # Cleanup.
--echo #
DROP DATABASE bup_nodata;
@@ -242,6 +262,8 @@
--remove_file $MYSQLTEST_VARDIR/master-data/bup_data.bak
--error 0,1
--remove_file $MYSQLTEST_VARDIR/master-data/bup_nodata.bak
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_notables.bak
UNINSTALL PLUGIN example;
=== modified file 'sql/si_objects.cc'
--- a/sql/si_objects.cc 2008-12-06 00:02:44 +0000
+++ b/sql/si_objects.cc 2008-12-17 10:27:06 +0000
@@ -161,6 +161,25 @@
///////////////////////////////////////////////////////////////////////////
/**
+ Update THD with the warnings from the given list.
+
+ @param[in] thd Thread context.
+ @parampin] src Warning list.
+*/
+
+void copy_warnings(THD *thd, List<MYSQL_ERROR> *src)
+{
+ List_iterator_fast<MYSQL_ERROR> err_it(*src);
+ MYSQL_ERROR *err;
+
+ while ((err= err_it++))
+ push_warning(thd, err->level, err->code, err->msg);
+}
+
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+
+/**
Execute one DML statement in a backup-specific context. Result set and
warning information are stored in the output parameter. Some session
attributes are preserved and reset to predefined values before query
@@ -168,7 +187,8 @@
@param[in] thd Thread context.
@param[in] query SQL query to be executed.
- @param[out] ed_result A place to store result and warnings.
+ @param[in] get_warnings If true, update THD with warnings.
+ @param[out] ed_connection A place to store result and warnings.
@return Error status.
@retval TRUE on error.
@@ -177,7 +197,7 @@
bool
run_service_interface_sql(THD *thd, Ed_connection *ed_connection,
- const LEX_STRING *query)
+ const LEX_STRING *query, bool get_warnings)
{
Si_session_context session_context;
@@ -191,6 +211,11 @@
bool rc= ed_connection->execute_direct(*query);
+ if (get_warnings) {
+ /* Push warnings on the THD error stack. */
+ copy_warnings(thd, ed_connection->get_warn_list());
+ }
+
session_context.restore_si_ctx(thd);
DBUG_RETURN(rc);
@@ -200,25 +225,6 @@
///////////////////////////////////////////////////////////////////////////
/**
- Update THD with the warnings from the given list.
-
- @param[in] thd Thread context.
- @parampin] src Warning list.
-*/
-
-void copy_warnings(THD *thd, List<MYSQL_ERROR> *src)
-{
- List_iterator_fast<MYSQL_ERROR> err_it(*src);
- MYSQL_ERROR *err;
-
- while ((err= err_it++))
- push_warning(thd, err->level, err->code, err->msg);
-}
-
-///////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////
-
-/**
Table_name_key defines a hash key, which includes database and tables
names.
*/
@@ -1285,7 +1291,7 @@
Ed_result_set *ed_result_set;
Iterator *it;
- if (run_service_interface_sql(thd, &ed_connection, query) ||
+ if (run_service_interface_sql(thd, &ed_connection, query, true) ||
ed_connection.get_warn_count())
{
/* There should be no warnings. */
@@ -1754,7 +1760,8 @@
s_stream <<
"SHOW CREATE DATABASE `" << get_name() << "`";
- if (run_service_interface_sql(thd, &ed_connection, s_stream.lex_string()) ||
+ if (run_service_interface_sql(thd, &ed_connection,
+ s_stream.lex_string(), true) ||
ed_connection.get_warn_count())
{
/*
@@ -1823,7 +1830,8 @@
s_stream <<
"SHOW CREATE TABLE `" << &m_db_name << "`.`" << &m_id
<< "`";
- if (run_service_interface_sql(thd, &ed_connection, s_stream.lex_string()) ||
+ if (run_service_interface_sql(thd, &ed_connection,
+ s_stream.lex_string(), true) ||
ed_connection.get_warn_count())
{
/*
@@ -1878,7 +1886,8 @@
"SHOW CREATE VIEW `" << view->get_db_name() << "`."
"`" << view->get_name() << "`";
- if (run_service_interface_sql(thd, &ed_connection, s_stream.lex_string()) ||
+ if (run_service_interface_sql(thd, &ed_connection,
+ s_stream.lex_string(), true) ||
ed_connection.get_warn_count())
{
/*
@@ -1988,7 +1997,8 @@
"SHOW CREATE " << get_type_name() <<
" `" << &m_db_name << "`.`" << &m_id << "`";
- if (run_service_interface_sql(thd, &ed_connection, s_stream.lex_string()) ||
+ if (run_service_interface_sql(thd, &ed_connection,
+ s_stream.lex_string(), true) ||
ed_connection.get_warn_count())
{
/*
@@ -2642,7 +2652,9 @@
s_stream << "SHOW CREATE DATABASE `" << db_name << "`";
Ed_connection ed_connection(thd);
- rc= run_service_interface_sql(thd, &ed_connection, s_stream.lex_string());
+ rc= run_service_interface_sql(thd,
+ &ed_connection, s_stream.lex_string(),
+ false);
/* We're not interested in warnings/errors here. */
@@ -2667,7 +2679,8 @@
"WHERE grantee = \"" << grant_obj->get_user_name() << "\"";
- if (run_service_interface_sql(thd, &ed_connection, s_stream.lex_string()) ||
+ if (run_service_interface_sql(thd, &ed_connection,
+ s_stream.lex_string(), true) ||
ed_connection.get_warn_count())
{
/* Should be no warnings. */
@@ -2710,7 +2723,8 @@
"t1.tablespace_name = '" << ts_name << "'";
- if (run_service_interface_sql(thd, &ed_connection, s_stream.lex_string()) ||
+ if (run_service_interface_sql(thd, &ed_connection,
+ s_stream.lex_string(), true) ||
ed_connection.get_warn_count())
{
/* Should be no warnings. */
@@ -2773,7 +2787,8 @@
"t3.table_name = '" << table_name << "'";
- if (run_service_interface_sql(thd, &ed_connection, s_stream.lex_string()) ||
+ if (run_service_interface_sql(thd, &ed_connection,
+ s_stream.lex_string(), true) ||
ed_connection.get_warn_count())
{
/* Should be no warnings. */
@@ -3092,7 +3107,7 @@
"FROM INFORMATION_SCHEMA.PROCESSLIST"
"WHERE LCASE(command) = LCASE('Binlog Dump')");
- if (run_service_interface_sql(thd, &ed_connection, &sql_text) ||
+ if (run_service_interface_sql(thd, &ed_connection, &sql_text, true) ||
ed_connection.get_warn_count())
{
/* Should be no warnings. */