diff options
Diffstat (limited to 'sql/log_event.cc')
-rw-r--r-- | sql/log_event.cc | 173 |
1 files changed, 36 insertions, 137 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc index 6b0e19f27cb..fc63b3b05f9 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -6425,15 +6425,29 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) */ if (!thd->lock) { - bool need_reopen= 1; /* To execute the first lap of the loop below */ - /* - lock_tables() reads the contents of thd->lex, so they must be - initialized. Contrary to in - Table_map_log_event::do_apply_event() we don't call - mysql_init_query() as that may reset the binlog format. + Lock_tables() reads the contents of thd->lex, so they must be + initialized. + + We also call the mysql_reset_thd_for_next_command(), since this + is the logical start of the next "statement". Note that this + call might reset the value of current_stmt_binlog_row_based, so + we need to do any changes to that value after this function. */ lex_start(thd); + mysql_reset_thd_for_next_command(thd); + + /* + Check if the slave is set to use SBR. If so, it should switch + to using RBR until the end of the "statement", i.e., next + STMT_END_F or next error. + */ + if (!thd->current_stmt_binlog_row_based && + mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG)) + { + thd->set_current_stmt_binlog_row_based(); + } + /* There are a few flags that are replicated with each row event. @@ -6452,72 +6466,23 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) /* A small test to verify that objects have consistent types */ DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS)); - - while ((error= lock_tables(thd, rli->tables_to_lock, - rli->tables_to_lock_count, &need_reopen))) + if (simple_open_n_lock_tables(thd, rli->tables_to_lock)) { - if (!need_reopen) - { - if (thd->is_slave_error || thd->is_fatal_error) - { - /* - Error reporting borrowed from Query_log_event with many excessive - simplifications (we don't honour --slave-skip-errors) - */ - uint actual_error= thd->main_da.sql_errno(); - rli->report(ERROR_LEVEL, actual_error, - "Error '%s' in %s event: when locking tables", - (actual_error ? thd->main_da.message(): - "unexpected success or fatal error"), - get_type_str()); - thd->is_fatal_error= 1; - } - else - { - rli->report(ERROR_LEVEL, error, - "Error in %s event: when locking tables", - get_type_str()); - } - const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); - DBUG_RETURN(error); - } - - /* - So we need to reopen the tables. - - We need to flush the pending RBR event, since it keeps a - pointer to an open table. - - ALTERNATIVE SOLUTION (not implemented): Extract a pointer to - the pending RBR event and reset the table pointer after the - tables has been reopened. - - NOTE: For this new scheme there should be no pending event: - need to add code to assert that is the case. - */ - thd->binlog_flush_pending_rows_event(false); - TABLE_LIST *tables= rli->tables_to_lock; - close_tables_for_reopen(thd, &tables); - - uint tables_count= rli->tables_to_lock_count; - if ((error= open_tables(thd, &tables, &tables_count, 0))) + uint actual_error= thd->main_da.sql_errno(); + if (thd->is_slave_error || thd->is_fatal_error) { - if (thd->is_slave_error || thd->is_fatal_error) - { - /* - Error reporting borrowed from Query_log_event with many excessive - simplifications (we don't honour --slave-skip-errors) - */ - uint actual_error= thd->main_da.sql_errno(); - rli->report(ERROR_LEVEL, actual_error, - "Error '%s' on reopening tables", - (actual_error ? thd->main_da.message() : - "unexpected success or fatal error")); - thd->is_slave_error= 1; - } - const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); - DBUG_RETURN(error); + /* + Error reporting borrowed from Query_log_event with many excessive + simplifications (we don't honour --slave-skip-errors) + */ + rli->report(ERROR_LEVEL, actual_error, + "Error '%s' on opening tables", + (actual_error ? thd->main_da.message() : + "unexpected success or fatal error")); + thd->is_slave_error= 1; } + const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); + DBUG_RETURN(actual_error); } /* @@ -6570,6 +6535,8 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) table= m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id); + DBUG_PRINT("debug", ("m_table: 0x%lx, m_table_id: %lu", (ulong) m_table, m_table_id)); + if (table) { /* @@ -7293,71 +7260,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) } else { - /* - open_tables() reads the contents of thd->lex, so they must be - initialized, so we should call lex_start(); to be even safer, we - call mysql_init_query() which does a more complete set of inits. - */ - lex_start(thd); - mysql_reset_thd_for_next_command(thd); - /* - Check if the slave is set to use SBR. If so, it should switch - to using RBR until the end of the "statement", i.e., next - STMT_END_F or next error. - */ - if (!thd->current_stmt_binlog_row_based && - mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG)) - { - thd->set_current_stmt_binlog_row_based(); - } - - /* - Open the table if it is not already open and add the table to - table map. Note that for any table that should not be - replicated, a filter is needed. - - The creation of a new TABLE_LIST is used to up-cast the - table_list consisting of RPL_TABLE_LIST items. This will work - since the only case where the argument to open_tables() is - changed, is when thd->lex->query_tables == table_list, i.e., - when the statement requires prelocking. Since this is not - executed when a statement is executed, this case will not occur. - As a precaution, an assertion is added to ensure that the bad - case is not a fact. - - Either way, the memory in the list is *never* released - internally in the open_tables() function, hence we take a copy - of the pointer to make sure that it's not lost. - */ - uint count; DBUG_ASSERT(thd->lex->query_tables != table_list); - TABLE_LIST *tmp_table_list= table_list; - if ((error= open_tables(thd, &tmp_table_list, &count, 0))) - { - if (thd->is_slave_error || thd->is_fatal_error) - { - /* - Error reporting borrowed from Query_log_event with many excessive - simplifications (we don't honour --slave-skip-errors) - */ - uint actual_error= thd->main_da.sql_errno(); - rli->report(ERROR_LEVEL, actual_error, - "Error '%s' on opening table `%s`.`%s`", - (actual_error ? thd->main_da.message() : - "unexpected success or fatal error"), - table_list->db, table_list->table_name); - thd->is_slave_error= 1; - } - goto err; - } - - m_table= table_list->table; - - /* - This will fail later otherwise, the 'in_use' field should be - set to the current thread. - */ - DBUG_ASSERT(m_table->in_use); /* Use placement new to construct the table_def instance in the @@ -7383,10 +7286,6 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) } DBUG_RETURN(error); - -err: - my_free(memory, MYF(MY_WME)); - DBUG_RETURN(error); } Log_event::enum_skip_reason |