diff --git a/mysql-test/suite/binlog/r/binlog_bug38839.result b/mysql-test/suite/binlog/r/binlog_bug38839.result new file mode 100644 index 0000000000000..d68652f54bb93 --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_bug38839.result @@ -0,0 +1,11 @@ +SET sql_mode=''; +CREATE TEMPORARY TABLE t ENGINE=MyISAM AS SELECT @a AS c; +INSERT INTO t VALUES (0xABB0); +SET autocommit=OFF; +CREATE TABLE t (c INT PRIMARY KEY) ENGINE=MyISAM SELECT * FROM t FOR UPDATE; +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +SET autocommit=ON; +DROP TEMPORARY TABLE IF EXISTS t; +DROP TABLE IF EXISTS t; +Warnings: +Note 1051 Unknown table 'test.t' diff --git a/mysql-test/suite/binlog/t/binlog_bug38839.test b/mysql-test/suite/binlog/t/binlog_bug38839.test new file mode 100644 index 0000000000000..7e5923c10d44d --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_bug38839.test @@ -0,0 +1,17 @@ +# Test case for MDEV-38839 +# Assertion `(thd->state_flags & Open_tables_state::BACKUPS_AVAIL) || +# !thd->has_pending_row_events()' failed in close_thread_tables +# on CREATE TABLE ... SELECT * FROM temp_table FOR UPDATE in MIXED binlog mode + +--source include/have_log_bin.inc +--source include/have_binlog_format_mixed.inc + +SET sql_mode=''; +CREATE TEMPORARY TABLE t ENGINE=MyISAM AS SELECT @a AS c; +INSERT INTO t VALUES (0xABB0); +SET autocommit=OFF; +--error ER_DUP_ENTRY +CREATE TABLE t (c INT PRIMARY KEY) ENGINE=MyISAM SELECT * FROM t FOR UPDATE; +SET autocommit=ON; +DROP TEMPORARY TABLE IF EXISTS t; +DROP TABLE IF EXISTS t; diff --git a/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test b/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test index dab2e3f633a98..aa4aa215e0051 100644 --- a/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test +++ b/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test @@ -45,6 +45,7 @@ SET GLOBAL log_output = 'FILE'; connection master; #With '--force' option, mysql_upgrade always executes all sql statements for upgrading. +--disable_warnings ALTER TABLE mysql.slow_log DROP COLUMN thread_id, DROP COLUMN rows_affected; DROP DATABASE `mysqltest-1`; sync_slave_with_master; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 42723fb6caf62..179e7f87dec62 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -7147,12 +7147,22 @@ int THD::decide_logging_format(TABLE_LIST *tables) trans= table->file->has_transactions(); - if (share->tmp_table) - lex->set_stmt_accessed_table(trans ? LEX::STMT_WRITES_TEMP_TRANS_TABLE : - LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE); - else - lex->set_stmt_accessed_table(trans ? LEX::STMT_WRITES_TRANS_TABLE : - LEX::STMT_WRITES_NON_TRANS_TABLE); + /* + For SELECT ... FOR UPDATE, tbl->updating is false because the + table is only locked for reading, not actually being modified. + MyISAM has no row-level locking so FOR UPDATE escalates to + TL_WRITE, but this does not mean the table is being written to. + Only set the write flag when the table is actually being written. + */ + if (tbl->updating) + { + if (share->tmp_table) + lex->set_stmt_accessed_table(trans ? LEX::STMT_WRITES_TEMP_TRANS_TABLE : + LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE); + else + lex->set_stmt_accessed_table(trans ? LEX::STMT_WRITES_TRANS_TABLE : + LEX::STMT_WRITES_NON_TRANS_TABLE); + } flags_write_all_set &= flags; flags_write_some_set |= flags; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index ab7548cd2849d..f1931b7cb4c82 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -9100,6 +9100,9 @@ Item *LEX::create_item_func_nextval(THD *thd, Table_ident *table_ident) MDL_SHARED_WRITE)))) return NULL; thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); + // Sequence internally performs update hence updating flag marked true. + // This flag is used for bin log replication. + table->updating= true; return new (thd->mem_root) Item_func_nextval(thd, table); } @@ -9151,6 +9154,7 @@ Item *LEX::create_item_func_setval(THD *thd, Table_ident *table_ident, TL_WRITE_ALLOW_WRITE, MDL_SHARED_WRITE)))) return NULL; + table->updating= true; return new (thd->mem_root) Item_func_setval(thd, table, nextval, round, is_used); }