diff options
Diffstat (limited to 'sql/log.cc')
-rw-r--r-- | sql/log.cc | 105 |
1 files changed, 81 insertions, 24 deletions
diff --git a/sql/log.cc b/sql/log.cc index 4da22a07f85..5450e19172b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -38,6 +38,7 @@ #endif #include <mysql/plugin.h> +#include "rpl_handler.h" /* max size of the log message */ #define MAX_LOG_BUFFER_SIZE 1024 @@ -49,8 +50,7 @@ LOGGER logger; -MYSQL_BIN_LOG mysql_bin_log; -ulong sync_binlog_counter= 0; +MYSQL_BIN_LOG mysql_bin_log(&sync_binlog_period); static bool test_if_number(const char *str, long *res, bool allow_wildcards); @@ -976,6 +976,7 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length, uint user_host_len= 0; ulonglong query_utime, lock_utime; + DBUG_ASSERT(thd->enable_slow_log); /* Print the message to the buffer if we have slow log enabled */ @@ -2428,10 +2429,11 @@ const char *MYSQL_LOG::generate_name(const char *log_name, -MYSQL_BIN_LOG::MYSQL_BIN_LOG() +MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_period) :bytes_written(0), prepared_xids(0), file_id(1), open_count(1), need_start_event(TRUE), m_table_map_version(0), - is_relay_log(0), + sync_period_ptr(sync_period), + is_relay_log(0), signal_cnt(0), description_event_for_exec(0), description_event_for_queue(0) { /* @@ -3661,6 +3663,8 @@ bool MYSQL_BIN_LOG::append(Log_event* ev) } bytes_written+= ev->data_written; DBUG_PRINT("info",("max_size: %lu",max_size)); + if (flush_and_sync(0)) + goto err; if ((uint) my_b_append_tell(&log_file) > max_size) new_file_without_locking(); @@ -3691,6 +3695,8 @@ bool MYSQL_BIN_LOG::appendv(const char* buf, uint len,...) bytes_written += len; } while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint))); DBUG_PRINT("info",("max_size: %lu",max_size)); + if (flush_and_sync(0)) + goto err; if ((uint) my_b_append_tell(&log_file) > max_size) new_file_without_locking(); @@ -3700,17 +3706,21 @@ err: DBUG_RETURN(error); } - -bool MYSQL_BIN_LOG::flush_and_sync() +bool MYSQL_BIN_LOG::flush_and_sync(bool *synced) { int err=0, fd=log_file.file; + if (synced) + *synced= 0; safe_mutex_assert_owner(&LOCK_log); if (flush_io_cache(&log_file)) return 1; - if (++sync_binlog_counter >= sync_binlog_period && sync_binlog_period) + uint sync_period= get_sync_period(); + if (sync_period && ++sync_counter >= sync_period) { - sync_binlog_counter= 0; + sync_counter= 0; err=my_sync(fd, MYF(MY_WME)); + if (synced) + *synced= 1; } return err; } @@ -4001,7 +4011,7 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd, if (file == &log_file) { - error= flush_and_sync(); + error= flush_and_sync(0); if (!error) { signal_update(); @@ -4187,8 +4197,16 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) if (file == &log_file) // we are writing to the real log (disk) { - if (flush_and_sync()) + bool synced= 0; + if (flush_and_sync(&synced)) goto err; + + if (RUN_HOOK(binlog_storage, after_flush, + (thd, log_file_name, file->pos_in_file, synced))) { + sql_print_error("Failed to run 'after_flush' hooks"); + goto err; + } + signal_update(); rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED); } @@ -4443,7 +4461,7 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log) DBUG_ASSERT(carry == 0); if (sync_log) - flush_and_sync(); + return flush_and_sync(0); return 0; // All OK } @@ -4490,7 +4508,7 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd, bool lock) ev.write(&log_file); if (lock) { - if (!error && !(error= flush_and_sync())) + if (!error && !(error= flush_and_sync(0))) { signal_update(); rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED); @@ -4578,7 +4596,8 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event, if (incident && write_incident(thd, FALSE)) goto err; - if (flush_and_sync()) + bool synced= 0; + if (flush_and_sync(&synced)) goto err; DBUG_EXECUTE_IF("half_binlogged_transaction", abort();); if (cache->error) // Error on read @@ -4587,6 +4606,15 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event, write_error=1; // Don't give more errors goto err; } + + if (RUN_HOOK(binlog_storage, after_flush, + (thd, log_file_name, log_file.pos_in_file, synced))) + { + sql_print_error("Failed to run 'after_flush' hooks"); + write_error=1; + goto err; + } + signal_update(); } @@ -4623,12 +4651,9 @@ err: /** - Wait until we get a signal that the binary log has been updated. + Wait until we get a signal that the relay log has been updated. @param thd Thread variable - @param is_slave If 0, the caller is the Binlog_dump thread from master; - if 1, the caller is the SQL thread from the slave. This - influences only thd->proc_info. @note One must have a lock on LOCK_log before calling this function. @@ -4636,22 +4661,53 @@ err: THD::enter_cond() (see NOTES in sql_class.h). */ -void MYSQL_BIN_LOG::wait_for_update(THD* thd, bool is_slave) +void MYSQL_BIN_LOG::wait_for_update_relay_log(THD* thd) { const char *old_msg; - DBUG_ENTER("wait_for_update"); + DBUG_ENTER("wait_for_update_relay_log"); old_msg= thd->enter_cond(&update_cond, &LOCK_log, - is_slave ? - "Has read all relay log; waiting for the slave I/O " - "thread to update it" : - "Has sent all binlog to slave; waiting for binlog " - "to be updated"); + "Slave has read all relay log; " + "waiting for the slave I/O " + "thread to update it" ); pthread_cond_wait(&update_cond, &LOCK_log); thd->exit_cond(old_msg); DBUG_VOID_RETURN; } +/** + Wait until we get a signal that the binary log has been updated. + Applies to master only. + + NOTES + @param[in] thd a THD struct + @param[in] timeout a pointer to a timespec; + NULL means to wait w/o timeout. + @retval 0 if got signalled on update + @retval non-0 if wait timeout elapsed + @note + LOCK_log must be taken before calling this function. + LOCK_log is being released while the thread is waiting. + LOCK_log is released by the caller. +*/ + +int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd, + const struct timespec *timeout) +{ + int ret= 0; + const char* old_msg = thd->proc_info; + DBUG_ENTER("wait_for_update_bin_log"); + old_msg= thd->enter_cond(&update_cond, &LOCK_log, + "Master has sent all binlog to slave; " + "waiting for binlog to be updated"); + if (!timeout) + pthread_cond_wait(&update_cond, &LOCK_log); + else + ret= pthread_cond_timedwait(&update_cond, &LOCK_log, + const_cast<struct timespec *>(timeout)); + DBUG_RETURN(ret); +} + /** Close the log file. @@ -4864,6 +4920,7 @@ bool flush_error_log() void MYSQL_BIN_LOG::signal_update() { DBUG_ENTER("MYSQL_BIN_LOG::signal_update"); + signal_cnt++; pthread_cond_broadcast(&update_cond); DBUG_VOID_RETURN; } |