diff options
Diffstat (limited to 'sql/log.cc')
-rw-r--r-- | sql/log.cc | 104 |
1 files changed, 83 insertions, 21 deletions
diff --git a/sql/log.cc b/sql/log.cc index 124439ae9eb..225aaae0549 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -31,7 +31,7 @@ #include <stdarg.h> #include <m_ctype.h> // For test_if_number -MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log; +MYSQL_LOG mysql_log, mysql_slow_log, mysql_bin_log; ulong sync_binlog_counter= 0; static bool test_if_number(const char *str, @@ -86,7 +86,8 @@ static int find_uniq_filename(char *name) MYSQL_LOG::MYSQL_LOG() :bytes_written(0), last_time(0), query_start(0), name(0), file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), inited(0), - need_start_event(1) + need_start_event(1), description_event_for_exec(0), + description_event_for_queue(0) { /* We don't want to initialize LOCK_Log here as such initialization depends on @@ -114,6 +115,8 @@ void MYSQL_LOG::cleanup() { inited= 0; close(LOG_CLOSE_INDEX); + delete description_event_for_queue; + delete description_event_for_exec; (void) pthread_mutex_destroy(&LOCK_log); (void) pthread_mutex_destroy(&LOCK_index); (void) pthread_cond_destroy(&update_cond); @@ -183,7 +186,8 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, const char *new_name, const char *index_file_name_arg, enum cache_type io_cache_type_arg, bool no_auto_events_arg, - ulong max_size_arg) + ulong max_size_arg, + bool null_created_arg) { char buff[512]; File file= -1, index_file_nr= -1; @@ -281,8 +285,8 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, if (my_b_safe_write(&log_file, (byte*) BINLOG_MAGIC, BIN_LOG_HEADER_SIZE)) goto err; - bytes_written += BIN_LOG_HEADER_SIZE; - write_file_name_to_index_file=1; + bytes_written+= BIN_LOG_HEADER_SIZE; + write_file_name_to_index_file= 1; } if (!my_b_inited(&index_file)) @@ -312,10 +316,51 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, } if (need_start_event && !no_auto_events) { - need_start_event=0; - Start_log_event s; + /* + In 4.x we set need_start_event=0 here, but in 5.0 we want a Start event + even if this is not the very first binlog. + */ + Format_description_log_event s(BINLOG_VERSION); + if (!s.is_valid()) + goto err; s.set_log_pos(this); - s.write(&log_file); + if (null_created_arg) + s.created= 0; + if (s.write(&log_file)) + goto err; + bytes_written+= s.get_event_len(); + } + if (description_event_for_queue && + description_event_for_queue->binlog_version>=4) + { + /* + This is a relay log written to by the I/O slave thread. + Write the event so that others can later know the format of this relay + log. + Note that this event is very close to the original event from the + master (it has binlog version of the master, event types of the + master), so this is suitable to parse the next relay log's event. It + has been produced by + Format_description_log_event::Format_description_log_event(char* + buf,). + Why don't we want to write the description_event_for_queue if this event + is for format<4 (3.23 or 4.x): this is because in that case, the + description_event_for_queue describes the data received from the master, + but not the data written to the relay log (*conversion*), which is in + format 4 (slave's). + */ + /* + Set 'created' to 0, so that in next relay logs this event does not trigger + cleaning actions on the slave in + Format_description_log_event::exec_event(). + Set 'log_pos' to 0 to show that it's an artificial event. + */ + description_event_for_queue->created= 0; + description_event_for_queue->log_pos= 0; + + if (description_event_for_queue->write(&log_file)) + goto err; + bytes_written+= description_event_for_queue->get_event_len(); } if (flush_io_cache(&log_file) || my_sync(log_file.file, MYF(MY_WME))) @@ -611,7 +656,7 @@ bool MYSQL_LOG::reset_logs(THD* thd) if (!thd->slave_thread) need_start_event=1; open(save_name, save_log_type, 0, index_file_name, - io_cache_type, no_auto_events, max_size); + io_cache_type, no_auto_events, max_size, 0); my_free((gptr) save_name, MYF(0)); err: @@ -1001,8 +1046,17 @@ void MYSQL_LOG::new_file(bool need_lock) Note that at this point, log_type != LOG_CLOSED (important for is_open()). */ + /* + new_file() is only used for rotation (in FLUSH LOGS or because size > + max_binlog_size or max_relay_log_size). + If this is a binary log, the Format_description_log_event at the beginning of + the new file should have created=0 (to distinguish with the + Format_description_log_event written at server startup, which should + trigger temp tables deletion on slaves. + */ + open(old_name, save_log_type, new_name_ptr, index_file_name, io_cache_type, - no_auto_events, max_size); + no_auto_events, max_size, 1); if (this == &mysql_bin_log) report_pos_in_innodb(); my_free(old_name,MYF(0)); @@ -1086,7 +1140,7 @@ err: /* Write to normal (not rotable) log - This is the format for the 'normal', 'slow' and 'update' logs. + This is the format for the 'normal' log. */ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, @@ -1177,11 +1231,15 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, inline bool sync_binlog(IO_CACHE *cache) { - return (sync_binlog_period && - (sync_binlog_period == ++sync_binlog_counter) && - (sync_binlog_counter= 0, my_sync(cache->file, MYF(MY_WME)))); + if (sync_binlog_period == ++sync_binlog_counter && sync_binlog_period) + { + sync_binlog_counter= 0; + return my_sync(cache->file, MYF(MY_WME)); + } + return 0; } + /* Write an event to the binary log */ @@ -1349,6 +1407,12 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u", } #endif +#if MYSQL_VERSION_ID < 50000 + /* + In 5.0 this is not needed anymore as we store the value of + FOREIGN_KEY_CHECKS in a binary way in the Query event's header. + The code below was enabled in 4.0 and 4.1. + */ /* If the user has set FOREIGN_KEY_CHECKS=0 we wrap every SQL command in the binlog inside: @@ -1364,6 +1428,7 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u", if (e.write(file)) goto err; } +#endif } /* Write the SQL command */ @@ -1374,6 +1439,7 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u", /* Write log events to reset the 'run environment' of the SQL command */ +#if MYSQL_VERSION_ID < 50000 if (thd && thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) { Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=1", 24, 0); @@ -1381,6 +1447,7 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u", if (e.write(file)) goto err; } +#endif /* Tell for transactional table handlers up to which position in the @@ -1646,8 +1713,7 @@ err: /* - Write update log in a format suitable for incremental backup - This is also used by the slow query log. + Write to the slow query log. */ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, @@ -1663,11 +1729,6 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, int tmp_errno=0; char buff[80],*end; end=buff; - if (!(thd->options & OPTION_UPDATE_LOG)) - { - VOID(pthread_mutex_unlock(&LOCK_log)); - return 0; - } if (!(specialflag & SPECIAL_SHORT_LOG_FORMAT) || query_start_arg) { current_time=time(NULL); @@ -1834,6 +1895,7 @@ void MYSQL_LOG::close(uint exiting) Stop_log_event s; s.set_log_pos(this); s.write(&log_file); + bytes_written+= s.get_event_len(); signal_update(); } #endif /* HAVE_REPLICATION */ |