Commit 221ced92 authored by Daniel Black's avatar Daniel Black

MDEV-4875 Can't restore a mysqldump if --add-drop-database meets general_log

or slow query log when the log_output=TABLE.

When this happens, we temporary disable by changing log_output until
we've created the general_log and slow_log tables again.

Move </database> in xml mode until after the transaction_registry.

General_log and slow_log tables where moved to be first to be dumped so
that the disabling of the general/slow queries is minimal.
parent 9fe3bc2a
......@@ -5229,6 +5229,55 @@ int init_dumping_views(char *qdatabase __attribute__((unused)))
} /* init_dumping_views */
/*
mysql specific database initialization.
SYNOPSIS
init_dumping_mysql_tables
protections around dumping general/slow query log
qdatabase quoted name of the "mysql" database
RETURN VALUES
0 Success.
1 Failure.
*/
static int init_dumping_mysql_tables(char *qdatabase)
{
DBUG_ENTER("init_dumping_mysql_tables");
if (opt_drop_database)
fprintf(md_result_file,
"\n/*!50106 SET @save_log_output=@@LOG_OUTPUT*/;\n"
"/*M!100203 EXECUTE IMMEDIATE IF(@@LOG_OUTPUT='TABLE' AND (@@SLOW_QUERY_LOG=1 OR @@GENERAL_LOG=1),"
"\"SET GLOBAL LOG_OUTPUT='NONE'\", \"DO 0\") */;\n");
DBUG_RETURN(init_dumping_tables(qdatabase));
}
static void dump_first_mysql_tables(char *database)
{
char table_type[NAME_LEN];
char ignore_flag;
DBUG_ENTER("dump_first_mysql_tables");
if (!get_table_structure((char *) "general_log",
database, table_type, &ignore_flag) )
verbose_msg("-- Warning: get_table_structure() failed with some internal "
"error for 'general_log' table\n");
if (!get_table_structure((char *) "slow_log",
database, table_type, &ignore_flag) )
verbose_msg("-- Warning: get_table_structure() failed with some internal "
"error for 'slow_log' table\n");
/* general and slow query logs exist now */
if (opt_drop_database)
fprintf(md_result_file,
"\n/*!50106 SET GLOBAL LOG_OUTPUT=@save_log_output*/;\n\n");
DBUG_VOID_RETURN;
}
/*
Table Specific database initialization.
......@@ -5335,7 +5384,6 @@ static int dump_all_tables_in_db(char *database)
char table_buff[NAME_LEN*2+3];
char hash_key[2*NAME_LEN+2]; /* "db.tablename" */
char *afterdot;
my_bool general_log_table_exists= 0, slow_log_table_exists=0;
my_bool transaction_registry_table_exists= 0;
int using_mysql_db= !my_strcasecmp(charset_info, database, "mysql");
DBUG_ENTER("dump_all_tables_in_db");
......@@ -5343,11 +5391,15 @@ static int dump_all_tables_in_db(char *database)
afterdot= strmov(hash_key, database);
*afterdot++= '.';
if (init_dumping(database, init_dumping_tables))
if (init_dumping(database, using_mysql_db ? init_dumping_mysql_tables
: init_dumping_tables))
DBUG_RETURN(1);
if (opt_xml)
print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS);
if (using_mysql_db)
dump_first_mysql_tables(database);
if (lock_tables)
{
DYNAMIC_STRING query;
......@@ -5436,24 +5488,16 @@ static int dump_all_tables_in_db(char *database)
else
{
/*
If general_log and slow_log exists in the 'mysql' database,
If transaction_registry exists in the 'mysql' database,
we should dump the table structure. But we cannot
call get_table_structure() here as 'LOCK TABLES' query got executed
above on the session and that 'LOCK TABLES' query does not contain
'general_log' and 'slow_log' tables. (you cannot acquire lock
on log tables). Hence mark the existence of these log tables here and
'transaction_registry'. Hence mark the existence of the table here and
after 'UNLOCK TABLES' query is executed on the session, get the table
structure from server and dump it in the file.
*/
if (using_mysql_db)
{
if (!my_strcasecmp(charset_info, table, "general_log"))
general_log_table_exists= 1;
else if (!my_strcasecmp(charset_info, table, "slow_log"))
slow_log_table_exists= 1;
else if (!my_strcasecmp(charset_info, table, "transaction_registry"))
transaction_registry_table_exists= 1;
}
if (using_mysql_db && !my_strcasecmp(charset_info, table, "transaction_registry"))
transaction_registry_table_exists= 1;
}
}
......@@ -5474,39 +5518,25 @@ static int dump_all_tables_in_db(char *database)
DBUG_PRINT("info", ("Dumping routines for database %s", database));
dump_routines_for_db(database);
}
if (opt_xml)
{
fputs("</database>\n", md_result_file);
check_io(md_result_file);
}
if (lock_tables)
(void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES");
if (using_mysql_db)
{
char table_type[NAME_LEN];
char ignore_flag;
if (general_log_table_exists)
{
if (!get_table_structure((char *) "general_log",
database, table_type, &ignore_flag) )
verbose_msg("-- Warning: get_table_structure() failed with some internal "
"error for 'general_log' table\n");
}
if (slow_log_table_exists)
{
if (!get_table_structure((char *) "slow_log",
database, table_type, &ignore_flag) )
verbose_msg("-- Warning: get_table_structure() failed with some internal "
"error for 'slow_log' table\n");
}
if (transaction_registry_table_exists)
{
char table_type[NAME_LEN];
char ignore_flag;
if (!get_table_structure((char *) "transaction_registry",
database, table_type, &ignore_flag) )
verbose_msg("-- Warning: get_table_structure() failed with some internal "
"error for 'transaction_registry' table\n");
}
}
if (opt_xml)
{
fputs("</database>\n", md_result_file);
check_io(md_result_file);
}
if (flush_privileges && using_mysql_db)
{
fprintf(md_result_file,"\n--\n-- Flush Grant Tables \n--\n");
......
This diff is collapsed.
......@@ -2916,4 +2916,64 @@ DROP DATABASE test2;
SET sql_mode=@save_sql_mode;
--remove_file $MYSQLTEST_VARDIR/tmp/dumptest1.sql
--echo #
--echo # MDEV-4875 Can't restore a mysqldump if --add-drop-database meets general_log
--echo #
CREATE DATABASE test1;
--echo # Dump mysql database
--exec $MYSQL_DUMP --add-drop-database --databases mysql test1 > $MYSQLTEST_VARDIR/tmp/dumptest1.sql
--disable_warnings
DROP VIEW IF EXISTS mysql.user;
DROP TABLE IF EXISTS mysql.global_priv;
DROP TABLE IF EXISTS mysql.user;
--enable_warnings
#DROP TABLE IF EXISTS mysql.transaction_registry;
#DROP TABLE IF EXISTS mysql.slow_log;
#DROP TABLE IF EXISTS mysql.general_log;
DROP TABLE IF EXISTS mysql.time_zone_transition_type;
DROP TABLE IF EXISTS mysql.time_zone_transition;
DROP TABLE IF EXISTS mysql.time_zone_name;
DROP TABLE IF EXISTS mysql.time_zone_leap_second;
DROP TABLE IF EXISTS mysql.time_zone;
DROP TABLE IF EXISTS mysql.tables_priv;
DROP TABLE IF EXISTS mysql.table_stats;
DROP TABLE IF EXISTS mysql.servers;
DROP TABLE IF EXISTS mysql.roles_mapping;
DROP TABLE IF EXISTS mysql.proxies_priv;
DROP TABLE IF EXISTS mysql.procs_priv;
DROP TABLE IF EXISTS mysql.proc;
DROP TABLE IF EXISTS mysql.plugin;
DROP TABLE IF EXISTS mysql.innodb_table_stats;
DROP TABLE IF EXISTS mysql.innodb_index_stats;
DROP TABLE IF EXISTS mysql.index_stats;
DROP TABLE IF EXISTS mysql.host;
DROP TABLE IF EXISTS mysql.help_topic;
DROP TABLE IF EXISTS mysql.help_relation;
DROP TABLE IF EXISTS mysql.help_keyword;
DROP TABLE IF EXISTS mysql.help_category;
DROP TABLE IF EXISTS mysql.gtid_slave_pos;
DROP TABLE IF EXISTS mysql.func;
DROP TABLE IF EXISTS mysql.event;
DROP TABLE IF EXISTS mysql.db;
DROP TABLE IF EXISTS mysql.columns_priv;
DROP TABLE IF EXISTS mysql.column_stats;
--echo # Abbreviated contents
--replace_regex /Create_time="[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}"/Create_time="TIMESTAMP"/
--exec $MYSQL_DUMP --xml --skip-comments --no-data --add-drop-database --databases mysql test1
SET @save_general_log=@@GENERAL_LOG;
SET GLOBAL LOG_OUTPUT='TABLE', GLOBAL GENERAL_LOG=1;
--echo # Restore mysql database while general log is active
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/dumptest1.sql
--echo # No failure at this stage is the object of the test
SELECT @@GLOBAL.LOG_OUTPUT, @@GLOBAL.GENERAL_LOG;
SET GLOBAL LOG_OUTPUT=DEFAULT, GLOBAL GENERAL_LOG=@save_general_log;
TRUNCATE TABLE mysql.general_log;
DROP DATABASE test1;
--remove_file $MYSQLTEST_VARDIR/tmp/dumptest1.sql
--echo # End of 10.3 tests
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment