mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-25334 FTWRL/Backup blocks DDL on temporary tables with binlog enabled, assertion fails in Diagnostics_area::set_error_status
Fixed by adding a MDL_BACKUP_COMMIT lock before altering temporary tables whose creation was logged to binary log (in which case the ALTER TABLE must also be logged)
This commit is contained in:
40
mysql-test/main/backup_lock_binlog.result
Normal file
40
mysql-test/main/backup_lock_binlog.result
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#
|
||||||
|
# MDEV-25334 FTWRL/Backup blocks DDL on temporary tables with binlog
|
||||||
|
# enabled assertion fails in Diagnostics_area::set_error_status
|
||||||
|
#
|
||||||
|
select @@binlog_format;
|
||||||
|
@@binlog_format
|
||||||
|
MIXED
|
||||||
|
connect con1,localhost,root,,;
|
||||||
|
connection default;
|
||||||
|
#
|
||||||
|
# Test 1
|
||||||
|
#
|
||||||
|
CREATE TEMPORARY TABLE tmp (a INT);
|
||||||
|
connection con1;
|
||||||
|
FLUSH TABLES WITH READ LOCK;
|
||||||
|
connection default;
|
||||||
|
SET lock_wait_timeout= 1;
|
||||||
|
ALTER TABLE tmp;
|
||||||
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
|
connection con1;
|
||||||
|
unlock tables;
|
||||||
|
connection default;
|
||||||
|
drop table tmp;
|
||||||
|
#
|
||||||
|
# Test 2 (In statement format to ensure temporary table gets logged)
|
||||||
|
#
|
||||||
|
set @@binlog_format=statement;
|
||||||
|
CREATE TEMPORARY TABLE tmp (a INT);
|
||||||
|
connection con1;
|
||||||
|
BACKUP STAGE START;
|
||||||
|
BACKUP STAGE BLOCK_COMMIT;
|
||||||
|
connection default;
|
||||||
|
SET lock_wait_timeout= 1;
|
||||||
|
ALTER TABLE tmp;
|
||||||
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
|
connection con1;
|
||||||
|
BACKUP STAGE end;
|
||||||
|
connection default;
|
||||||
|
drop table tmp;
|
||||||
|
disconnect con1;
|
49
mysql-test/main/backup_lock_binlog.test
Normal file
49
mysql-test/main/backup_lock_binlog.test
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
--source include/have_binlog_format_mixed_or_statement.inc
|
||||||
|
|
||||||
|
#
|
||||||
|
# Tests involving locks and binlog
|
||||||
|
#
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-25334 FTWRL/Backup blocks DDL on temporary tables with binlog
|
||||||
|
--echo # enabled assertion fails in Diagnostics_area::set_error_status
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
select @@binlog_format;
|
||||||
|
--connect (con1,localhost,root,,)
|
||||||
|
connection default;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Test 1
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TEMPORARY TABLE tmp (a INT);
|
||||||
|
--connection con1
|
||||||
|
FLUSH TABLES WITH READ LOCK;
|
||||||
|
--connection default
|
||||||
|
SET lock_wait_timeout= 1;
|
||||||
|
--error ER_LOCK_WAIT_TIMEOUT
|
||||||
|
ALTER TABLE tmp;
|
||||||
|
--connection con1
|
||||||
|
unlock tables;
|
||||||
|
--connection default
|
||||||
|
drop table tmp;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Test 2 (In statement format to ensure temporary table gets logged)
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
set @@binlog_format=statement;
|
||||||
|
CREATE TEMPORARY TABLE tmp (a INT);
|
||||||
|
--connection con1
|
||||||
|
BACKUP STAGE START;
|
||||||
|
BACKUP STAGE BLOCK_COMMIT;
|
||||||
|
--connection default
|
||||||
|
SET lock_wait_timeout= 1;
|
||||||
|
--error ER_LOCK_WAIT_TIMEOUT
|
||||||
|
ALTER TABLE tmp;
|
||||||
|
--connection con1
|
||||||
|
BACKUP STAGE end;
|
||||||
|
--connection default
|
||||||
|
drop table tmp;
|
||||||
|
--disconnect con1
|
@ -9574,7 +9574,8 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
|
|||||||
If such table exists, there must be a corresponding TABLE_SHARE in
|
If such table exists, there must be a corresponding TABLE_SHARE in
|
||||||
THD::all_temp_tables list.
|
THD::all_temp_tables list.
|
||||||
*/
|
*/
|
||||||
if (thd->find_tmp_table_share(alter_ctx.new_db.str, alter_ctx.new_name.str))
|
if (thd->find_tmp_table_share(alter_ctx.new_db.str,
|
||||||
|
alter_ctx.new_name.str))
|
||||||
{
|
{
|
||||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alter_ctx.new_alias.str);
|
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alter_ctx.new_alias.str);
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
@ -9715,6 +9716,17 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
|
|||||||
|
|
||||||
if (table->s->tmp_table == NO_TMP_TABLE)
|
if (table->s->tmp_table == NO_TMP_TABLE)
|
||||||
mysql_audit_alter_table(thd, table_list);
|
mysql_audit_alter_table(thd, table_list);
|
||||||
|
else if (table->s->table_creation_was_logged && mysql_bin_log.is_open())
|
||||||
|
{
|
||||||
|
/* Protect against MDL error in binary logging */
|
||||||
|
MDL_request mdl_request;
|
||||||
|
DBUG_ASSERT(!mdl_ticket);
|
||||||
|
mdl_request.init(MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
|
||||||
|
MDL_TRANSACTION);
|
||||||
|
if (thd->mdl_context.acquire_lock(&mdl_request,
|
||||||
|
thd->variables.lock_wait_timeout))
|
||||||
|
DBUG_RETURN(true);
|
||||||
|
}
|
||||||
|
|
||||||
THD_STAGE_INFO(thd, stage_setup);
|
THD_STAGE_INFO(thd, stage_setup);
|
||||||
|
|
||||||
@ -9794,9 +9806,12 @@ do_continue:;
|
|||||||
thd->get_stmt_da()->current_statement_warn_count());
|
thd->get_stmt_da()->current_statement_warn_count());
|
||||||
my_ok(thd, 0L, 0L, alter_ctx.tmp_buff);
|
my_ok(thd, 0L, 0L, alter_ctx.tmp_buff);
|
||||||
|
|
||||||
/* We don't replicate alter table statement on temporary tables */
|
/*
|
||||||
|
We don't replicate alter table statement on temporary tables
|
||||||
|
For which we did not log the CREATE TEMPORARY TABLE statement.
|
||||||
|
*/
|
||||||
if (table->s->tmp_table == NO_TMP_TABLE ||
|
if (table->s->tmp_table == NO_TMP_TABLE ||
|
||||||
!thd->is_current_stmt_binlog_format_row())
|
table->s->table_creation_was_logged)
|
||||||
{
|
{
|
||||||
if (write_bin_log(thd, true, thd->query(), thd->query_length()))
|
if (write_bin_log(thd, true, thd->query(), thd->query_length()))
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
|
Reference in New Issue
Block a user