diff --git a/sql/handler.cc b/sql/handler.cc index 0e1b2d62a4f..f4cd2901be1 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -385,17 +385,25 @@ int ha_report_binlog_offset_and_commit(THD *thd, #ifdef HAVE_INNOBASE_DB THD_TRANS *trans; trans = &thd->transaction.all; - if (trans->innobase_tid) + if (trans->innobase_tid && trans->innodb_active_trans) { + /* + If we updated some InnoDB tables (innodb_active_trans is true), the + binlog coords will be reported into InnoDB during the InnoDB commit + (innobase_report_binlog_offset_and_commit). But if we updated only + non-InnoDB tables, we need an explicit call to report it. + */ if ((error=innobase_report_binlog_offset_and_commit(thd, - trans->innobase_tid, - log_file_name, - end_offset))) + trans->innobase_tid, + log_file_name, + end_offset))) { my_error(ER_ERROR_DURING_COMMIT, MYF(0), error); error=1; } } + else if (opt_innodb_safe_binlog) // Don't report if not useful + innobase_store_binlog_offset_and_flush_log(log_file_name, end_offset); #endif return error; } diff --git a/sql/handler.h b/sql/handler.h index 3d5aaacb661..a9416b1b2c5 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -283,7 +283,7 @@ public: create_time(0), check_time(0), update_time(0), key_used_on_scan(MAX_KEY), active_index(MAX_KEY), ref_length(sizeof(my_off_t)), block_size(0), - raid_type(0), ft_handler(0), implicit_emptied(0), inited(NONE) + raid_type(0), ft_handler(0), inited(NONE), implicit_emptied(0) {} virtual ~handler(void) { /* TODO: DBUG_ASSERT(inited == NONE); */ } int ha_open(const char *name, int mode, int test_if_locked); diff --git a/sql/log.cc b/sql/log.cc index 89f8f2480e3..124439ae9eb 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2073,9 +2073,9 @@ bool MYSQL_LOG::cut_spurious_tail() name); DBUG_RETURN(1); } - sql_print_error("After InnoDB crash recovery, trying to truncate " - "the binary log '%s' at position %s corresponding to the " - "last committed transaction...", name, llstr(pos, llbuf1)); + sql_print_error("After InnoDB crash recovery, checking if the binary log " + "'%s' contains rolled back transactions which must be " + "removed from it...", name); /* If we have a too long binlog, cut. If too short, print error */ int fd= my_open(name, O_EXCL | O_APPEND | O_BINARY | O_WRONLY, MYF(MY_WME)); if (fd < 0) @@ -2091,10 +2091,17 @@ bool MYSQL_LOG::cut_spurious_tail() if (pos > (actual_size= my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME)))) { + /* + Note that when we have MyISAM rollback this error message should be + reconsidered. + */ sql_print_error("The binary log '%s' is shorter than its expected size " "(actual: %s, expected: %s) so it misses at least one " "committed transaction; so it should not be used for " - "replication.", name, llstr(actual_size, llbuf1), + "replication or point-in-time recovery. You would need " + "to restart slaves from a fresh master's data " + "snapshot ", + name, llstr(actual_size, llbuf1), llstr(pos, llbuf2)); error= 1; goto err; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 64739f348b4..eba37ed924b 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -869,7 +869,7 @@ extern ulong rpl_recovery_rank, thread_cache_size; extern ulong com_stat[(uint) SQLCOM_END], com_other, back_log; extern ulong specialflag, current_pid; extern ulong expire_logs_days, sync_binlog_period, sync_binlog_counter; -extern my_bool relay_log_purge; +extern my_bool relay_log_purge, opt_innodb_safe_binlog; extern uint test_flags,select_errors,ha_open_options; extern uint protocol_version, mysqld_port, dropping_tables; extern uint delay_key_write_options, lower_case_table_names; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b2d9266c0ce..7b36be3dd84 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2538,6 +2538,12 @@ server."); if (opt_innodb_safe_binlog) { + if (have_innodb != SHOW_OPTION_YES) + { + sql_print_error("Error: --innodb-safe-binlog is meaningful only if " + "the InnoDB storage engine is enabled in the server."); + unireg_abort(1); + } if (innobase_flush_log_at_trx_commit != 1) { sql_print_error("Warning: --innodb-safe-binlog is meaningful only if " @@ -4641,9 +4647,8 @@ replicating a LOAD DATA INFILE command.", effect). */ {"innodb_safe_binlog", OPT_INNODB_SAFE_BINLOG, - "After a crash recovery by InnoDB, truncate the binary log to the last \ -InnoDB committed transaction. Use only if this server updates ONLY InnoDB \ -tables.", + "After a crash recovery by InnoDB, truncate the binary log after the last " + "not-rolled-back statement/transaction.", (gptr*) &opt_innodb_safe_binlog, (gptr*) &opt_innodb_safe_binlog, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0}, #endif