From 11fc24ef24469acfd8ef95f5df1c691bfbed6074 Mon Sep 17 00:00:00 2001 From: "mats@romeo.(none)" <> Date: Thu, 12 Apr 2007 08:58:04 +0200 Subject: BUG#25688 (RBR: circular replication may cause STMT_END_F flags to be skipped): By moving statement end actions from Rows_log_event::do_apply_event() to Rows_log_event::do_update_pos() they will always be executed, even if Rows_log_event::do_apply_event() is skipped because the event originated at the same server. This because Rows_log_event::do_update_pos() is always executed (unless Rows_log_event::do_apply_event() failed with an error, in which case the slave stops with an error anyway). Adding test case. Fixing logic to detect if inside a group. If a rotate event occured when an initial prefix of events for a statement, but for which the table did contain a key, last_event_start_time is set to zero, causing rotate to end the group but without unlocking any tables. This left a lock hanging around, which subsequently triggered an assertion when a second attempt was made to lock the same sequence of tables. In order to solve the above problem, a new flag was added to the relay log info structure that is used to indicate that the replication thread is currently executing a statement. Using this flag, the replication thread is in a group if it is either in a statement or inside a trans- action. The patch also eliminates some gratuitous header file inclusions that were not needed (and caused compile errors) and replaced them with forward definitions. --- sql/rpl_rli.h | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'sql/rpl_rli.h') diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index 3f06e108f6d..234d24a9569 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -51,6 +51,17 @@ struct RPL_TABLE_LIST; typedef struct st_relay_log_info { + /** + Flags for the state of the replication. + */ + enum enum_state_flag { + /** The replication thread is inside a statement */ + IN_STMT, + + /** Flag counter. Should always be last */ + STATE_FLAGS_COUNT + }; + /* If flag set, then rli does not store its state in any info file. This is the case only when we execute BINLOG SQL commands inside @@ -314,6 +325,66 @@ typedef struct st_relay_log_info transaction). */ time_t last_event_start_time; + + /** + Helper function to do after statement completion. + + This function is called from an event to complete the group by + either stepping the group position, if the "statement" is not + inside a transaction; or increase the event position, if the + "statement" is inside a transaction. + + @param event_log_pos + Master log position of the event. The position is recorded in the + relay log info and used to produce information for SHOW + SLAVE STATUS. + + @param event_creation_time + Timestamp for the creation of the event on the master side. The + time stamp is recorded in the relay log info and used to compute + the Seconds_behind_master field. + */ + void stmt_done(my_off_t event_log_pos, + time_t event_creation_time); + + + /** + Set the value of a replication state flag. + + @param flag Flag to set + */ + void set_flag(enum_state_flag flag) + { + m_flags |= (1UL << flag); + } + + /** + Clear the value of a replication state flag. + + @param flag Flag to clear + */ + void clear_flag(enum_state_flag flag) + { + m_flags &= ~(1UL << flag); + } + + /** + Is the replication inside a group? + + Replication is inside a group if either: + - The OPTION_BEGIN flag is set, meaning we're inside a transaction + - The RLI_IN_STMT flag is set, meaning we're inside a statement + + @retval true Replication thread is currently inside a group + @retval false Replication thread is currently not inside a group + */ + bool is_in_group() const { + return (sql_thd->options & OPTION_BEGIN) || + (m_flags & (1UL << IN_STMT)); + } + +private: + uint32 m_flags; } RELAY_LOG_INFO; -- cgit v1.2.1