From e7cf871dda59ad39c9125288149a4ec38518d41c Mon Sep 17 00:00:00 2001 From: Andrei Date: Thu, 3 Mar 2022 17:47:54 +0200 Subject: MDEV-24617 OPTIMIZE on a sequence causes unexpected ER_BINLOG_UNSAFE_STATEMENT The warning out of OPTIMIZE Statement is unsafe because it uses a system function was indeed counterfactual and was resulted by checking an insufficiently strict property of lex' sql_command_flags. Fixed with deploying an additional checking of weather the current sql command that modifes a share->non_determinstic_insert table is capable of generating ROW format events. The extra check rules out the unsafety to OPTIMIZE et al, while the existing check continues to do so to CREATE TABLE (which is perculiarly tagged as ROW-event generative sql command). As a side effect sql_sequence.binlog test gets corrected and binlog_stm_unsafe_warning.test is reinforced to add up an unsafe CREATE..SELECT test. --- sql/sql_class.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql/sql_class.cc') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index bbc46408c04..7f5a6345770 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -6210,7 +6210,8 @@ int THD::decide_logging_format(TABLE_LIST *tables) table->file->ht) multi_write_engine= TRUE; if (share->non_determinstic_insert && - !(sql_command_flags[lex->sql_command] & CF_SCHEMA_CHANGE)) + (sql_command_flags[lex->sql_command] & CF_CAN_GENERATE_ROW_EVENTS + && !(sql_command_flags[lex->sql_command] & CF_SCHEMA_CHANGE))) has_write_tables_with_unsafe_statements= true; trans= table->file->has_transactions(); -- cgit v1.2.1 From 1766a18e06a056155031dabefb88ce7f201ad921 Mon Sep 17 00:00:00 2001 From: Vlad Lesin Date: Wed, 2 Mar 2022 21:29:53 +0300 Subject: MDEV-19577 Replication does not work with innodb_autoinc_lock_mode=2 The first step for deprecating innodb_autoinc_lock_mode(see MDEV-27844) is: - to switch statement binlog format to ROW if binlog format is MIXED and the statement changes autoincremented fields - issue warnings if innodb_autoinc_lock_mode == 2 and binlog format is STATEMENT --- sql/sql_class.cc | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'sql/sql_class.cc') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 7f5a6345770..c808a2c997c 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -6079,6 +6079,10 @@ int THD::decide_logging_format(TABLE_LIST *tables) bool is_write= FALSE; // If any write tables bool has_read_tables= FALSE; // If any read only tables bool has_auto_increment_write_tables= FALSE; // Write with auto-increment + /* true if it's necessary to switch current statement log format from + STATEMENT to ROW if binary log format is MIXED and autoincrement values + are changed in the statement */ + bool has_unsafe_stmt_autoinc_lock_mode= false; /* If a write table that doesn't have auto increment part first */ bool has_write_table_auto_increment_not_first_in_pk= FALSE; bool has_auto_increment_write_tables_not_first= FALSE; @@ -6200,6 +6204,8 @@ int THD::decide_logging_format(TABLE_LIST *tables) has_auto_increment_write_tables_not_first= found_first_not_own_table; if (share->next_number_keypart != 0) has_write_table_auto_increment_not_first_in_pk= true; + has_unsafe_stmt_autoinc_lock_mode= + table->file->autoinc_lock_mode_stmt_unsafe(); } } @@ -6268,6 +6274,9 @@ int THD::decide_logging_format(TABLE_LIST *tables) if (has_write_tables_with_unsafe_statements) lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); + if (has_unsafe_stmt_autoinc_lock_mode) + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_LOCK_MODE); + /* A query that modifies autoinc column in sub-statement can make the master and slave inconsistent. -- cgit v1.2.1