diff options
Diffstat (limited to 'sql/log.cc')
-rw-r--r-- | sql/log.cc | 73 |
1 files changed, 37 insertions, 36 deletions
diff --git a/sql/log.cc b/sql/log.cc index af1c4b79464..9ed594bfb36 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -153,7 +153,7 @@ private: class binlog_trx_data { public: binlog_trx_data() - : at_least_one_stmt(0), incident(FALSE), m_pending(0), + : at_least_one_stmt_committed(0), incident(FALSE), m_pending(0), before_stmt_pos(MY_OFF_T_UNDEF) { trans_log.end_of_file= max_binlog_cache_size; @@ -182,7 +182,10 @@ public: { DBUG_PRINT("info", ("truncating to position %lu", (ulong) pos)); DBUG_PRINT("info", ("before_stmt_pos=%lu", (ulong) pos)); - delete pending(); + if (pending()) + { + delete pending(); + } set_pending(0); reinit_io_cache(&trans_log, WRITE_CACHE, pos, 0, 0); trans_log.end_of_file= max_binlog_cache_size; @@ -192,12 +195,12 @@ public: /* The only valid positions that can be truncated to are at the beginning of a statement. We are relying on this fact to be able - to set the at_least_one_stmt flag correctly. In other word, if + to set the at_least_one_stmt_committed flag correctly. In other word, if we are truncating to the beginning of the transaction cache, there will be no statements in the cache, otherwhise, we will have at least one statement in the transaction cache. */ - at_least_one_stmt= (pos > 0); + at_least_one_stmt_committed= (pos > 0); } /* @@ -239,7 +242,7 @@ public: Boolean that is true if there is at least one statement in the transaction cache. */ - bool at_least_one_stmt; + bool at_least_one_stmt_committed; bool incident; private: @@ -1035,14 +1038,10 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command, Log_event_handler **current_handler= general_log_handler_list; char user_host_buff[MAX_USER_HOST_SIZE + 1]; Security_context *sctx= thd->security_ctx; - ulong id; uint user_host_len= 0; time_t current_time; - if (thd) - id= thd->thread_id; /* Normal thread */ - else - id= 0; /* Log from connect handler */ + DBUG_ASSERT(thd); lock_shared(); if (!opt_log) @@ -1061,7 +1060,7 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command, while (*current_handler) error|= (*current_handler++)-> log_general(thd, current_time, user_host_buff, - user_host_len, id, + user_host_len, thd->thread_id, command_name[(uint) command].str, command_name[(uint) command].length, query, query_length, @@ -1287,7 +1286,7 @@ static bool stmt_has_updated_trans_table(THD *thd) { Ha_trx_info *ha_info; - for (ha_info= thd->transaction.stmt.ha_list; ha_info; ha_info= ha_info->next()) + for (ha_info= thd->transaction.stmt.ha_list; ha_info && ha_info->is_started(); ha_info= ha_info->next()) { if (ha_info->is_trx_read_write() && ha_info->ht() != binlog_hton) return (TRUE); @@ -1535,9 +1534,9 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all) /* We commit the transaction if: - - We are not in a transaction and committing a statement, or + - We are not in a transaction and committing a statement, or - - We are in a transaction and a full transaction is committed + - We are in a transaction and a full transaction is committed Otherwise, we accumulate the statement */ @@ -1550,21 +1549,18 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all) YESNO(in_transaction), YESNO(thd->transaction.all.modified_non_trans_table), YESNO(thd->transaction.stmt.modified_non_trans_table))); - if (thd->options & OPTION_BIN_LOG) - { - if (!in_transaction || all) - { - Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0); - error= binlog_end_trans(thd, trx_data, &qev, all); - goto end; - } - } - else + + if (!in_transaction || all || + (!all && !trx_data->at_least_one_stmt_committed && + !stmt_has_updated_trans_table(thd) && + thd->transaction.stmt.modified_non_trans_table)) { - trx_data->reset(); + Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0); + error= binlog_end_trans(thd, trx_data, &qev, all); } -end: + trx_data->at_least_one_stmt_committed = my_b_tell(&trx_data->trans_log) > 0; + if (!all) trx_data->before_stmt_pos = MY_OFF_T_UNDEF; // part of the stmt commit DBUG_RETURN(error); @@ -1630,15 +1626,18 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) { /* We flush the cache with a rollback, wrapped in a beging/rollback if: - . aborting a transcation that modified a non-transactional table or; + . aborting a transaction that modified a non-transactional table; . aborting a statement that modified both transactional and - non-transctional tables but which is not in the boundaries of any - transaction; + non-transactional tables but which is not in the boundaries of any + transaction or there was no early change; . the OPTION_KEEP_LOG is activate. */ if ((all && thd->transaction.all.modified_non_trans_table) || (!all && thd->transaction.stmt.modified_non_trans_table && !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT))) || + (!all && thd->transaction.stmt.modified_non_trans_table && + !trx_data->at_least_one_stmt_committed && + thd->current_stmt_binlog_row_based) || ((thd->options & OPTION_KEEP_LOG))) { Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, TRUE, 0); @@ -1730,7 +1729,7 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv) int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); int const error= thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query, thd->query_length, TRUE, FALSE, errcode); + thd->query(), thd->query_length(), TRUE, FALSE, errcode); DBUG_RETURN(error); } @@ -1749,7 +1748,7 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv) int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); int error= thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query, thd->query_length, TRUE, FALSE, errcode); + thd->query(), thd->query_length(), TRUE, FALSE, errcode); DBUG_RETURN(error); } binlog_trans_log_truncate(thd, *(my_off_t*)sv); @@ -3641,7 +3640,7 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock) } old_name=name; name=0; // Don't free name - close(LOG_CLOSE_TO_BE_OPENED); + close(LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX); /* Note that at this point, log_state != LOG_CLOSED (important for is_open()). @@ -3656,8 +3655,10 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock) trigger temp tables deletion on slaves. */ - open(old_name, log_type, new_name_ptr, - io_cache_type, no_auto_events, max_size, 1); + /* reopen index binlog file, BUG#34582 */ + if (!open_index_file(index_file_name, 0)) + open(old_name, log_type, new_name_ptr, + io_cache_type, no_auto_events, max_size, 1); my_free(old_name,MYF(0)); end: @@ -4096,8 +4097,8 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) binlog_[wild_]{do|ignore}_table?" (WL#1049)" */ const char *local_db= event_info->get_db(); - if ((thd && !(thd->options & OPTION_BIN_LOG)) || - (!binlog_filter->db_ok(local_db))) + if ((!(thd->options & OPTION_BIN_LOG)) || + (!binlog_filter->db_ok(local_db))) { VOID(pthread_mutex_unlock(&LOCK_log)); DBUG_RETURN(0); |