From df7c1e816515da233972508347ece5c75fd28de7 Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Mon, 14 Jul 2003 14:59:26 +0300 Subject: [PATCH] Better fix for bug #791: At binlog rotation, INSERTs may not find their way into the binlog --- mysql-test/t/rpl_flush_log_loop.test | 1 + sql/log.cc | 30 +++++++++++++++------------- sql/mysqld.cc | 4 ++-- sql/slave.cc | 6 +++--- sql/sql_class.h | 12 +++++++---- 5 files changed, 30 insertions(+), 23 deletions(-) diff --git a/mysql-test/t/rpl_flush_log_loop.test b/mysql-test/t/rpl_flush_log_loop.test index c68fbb7111a..8a3da1a2b02 100644 --- a/mysql-test/t/rpl_flush_log_loop.test +++ b/mysql-test/t/rpl_flush_log_loop.test @@ -14,6 +14,7 @@ slave stop; eval change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=$SLAVE_MYPORT; slave start; +sleep 5; flush logs; sleep 5; --replace_result $SLAVE_MYPORT SLAVE_PORT diff --git a/sql/log.cc b/sql/log.cc index 1960c7d7cde..e4bdcf55534 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -109,7 +109,7 @@ void MYSQL_LOG::cleanup() if (inited) { inited= 0; - close(1); + close(LOG_CLOSE_INDEX); (void) pthread_mutex_destroy(&LOCK_log); (void) pthread_mutex_destroy(&LOCK_index); (void) pthread_cond_destroy(&update_cond); @@ -315,6 +315,7 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, break; } case LOG_CLOSED: // Impossible + case LOG_TO_BE_OPENED: DBUG_ASSERT(1); break; } @@ -332,7 +333,7 @@ shutdown the MySQL server and restart it.", log_name, errno); end_io_cache(&log_file); end_io_cache(&index_file); safeFree(name); - log_type=LOG_CLOSED; + log_type= LOG_CLOSED; DBUG_RETURN(1); } @@ -565,7 +566,7 @@ bool MYSQL_LOG::reset_logs(THD* thd) save_name=name; name=0; // Protect against free save_log_type=log_type; - close(0); // Don't close the index file + close(LOG_CLOSE_TO_BE_OPENED); /* First delete all old log files */ @@ -583,7 +584,7 @@ bool MYSQL_LOG::reset_logs(THD* thd) } /* Start logging with a new file */ - close(1); // Close index file + close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT); my_delete(index_file_name, MYF(MY_WME)); // Reset (open will update) if (!thd->slave_thread) need_start_event=1; @@ -865,7 +866,7 @@ void MYSQL_LOG::new_file(bool need_lock) old_name=name; save_log_type=log_type; name=0; // Don't free name - close(); + close(LOG_CLOSE_TO_BE_OPENED); /* Note that at this point, log_type == LOG_CLOSED (important for is_open()). @@ -1528,24 +1529,25 @@ void MYSQL_LOG:: wait_for_update(THD* thd) SYNOPSIS close() - exiting Set to 1 if we should also close the index file - This can be set to 0 if we are going to do call open - at once after close, in which case we don't want to - close the index file. - We only write a 'stop' event to the log if exiting is set + exiting Bitmask for one or more of the following bits: + LOG_CLOSE_INDEX if we should close the index file + LOG_CLOSE_TO_BE_OPENED if we intend to call open + at once after close. + LOG_CLOSE_STOP_EVENT write a 'stop' event to the log NOTES One can do an open on the object at once after doing a close. The internal structures are not freed until cleanup() is called */ -void MYSQL_LOG::close(bool exiting) +void MYSQL_LOG::close(uint exiting) { // One can't set log_type here! DBUG_ENTER("MYSQL_LOG::close"); DBUG_PRINT("enter",("exiting: %d", (int) exiting)); if (is_open()) { - if (log_type == LOG_BIN && !no_auto_events && exiting) + if (log_type == LOG_BIN && !no_auto_events && + (exiting & LOG_CLOSE_STOP_EVENT)) { Stop_log_event s; s.set_log_pos(this); @@ -1565,7 +1567,7 @@ void MYSQL_LOG::close(bool exiting) called a not complete close earlier and the index file is still open. */ - if (exiting && my_b_inited(&index_file)) + if ((exiting & LOG_CLOSE_INDEX) && my_b_inited(&index_file)) { end_io_cache(&index_file); if (my_close(index_file.file, MYF(0)) < 0 && ! write_error) @@ -1574,7 +1576,7 @@ void MYSQL_LOG::close(bool exiting) sql_print_error(ER(ER_ERROR_ON_WRITE), index_file_name, errno); } } - log_type= LOG_CLOSED; + log_type= (exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED; safeFree(name); DBUG_VOID_RETURN; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 88ae612950e..9b8d12e845d 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4210,8 +4210,8 @@ static void usage(void) puts("\ Copyright (C) 2000 MySQL AB, by Monty and others\n\ This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL license\n\ -Starts the MySQL server\n"); +and you are welcome to modify and redistribute it under the GPL license\n\n\ +Starts the MySQL database server\n"); printf("Usage: %s [OPTIONS]\n", my_progname); #ifdef __WIN__ diff --git a/sql/slave.cc b/sql/slave.cc index 557e288539b..6ace446a341 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1314,7 +1314,7 @@ file '%s')", fname); if (info_fd >= 0) my_close(info_fd, MYF(0)); rli->info_fd= -1; - rli->relay_log.close(1); + rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT); pthread_mutex_unlock(&rli->data_lock); DBUG_RETURN(1); } @@ -1374,7 +1374,7 @@ err: if (info_fd >= 0) my_close(info_fd, MYF(0)); rli->info_fd= -1; - rli->relay_log.close(1); + rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT); pthread_mutex_unlock(&rli->data_lock); DBUG_RETURN(1); } @@ -2989,7 +2989,7 @@ void end_relay_log_info(RELAY_LOG_INFO* rli) rli->cur_log_fd = -1; } rli->inited = 0; - rli->relay_log.close(1); + rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT); DBUG_VOID_RETURN; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 9908f034d7b..dcc839e13b1 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -30,11 +30,11 @@ class Slave_log_event; enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE }; enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY }; enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_IGNORE }; -enum enum_log_type { LOG_CLOSED, LOG_NORMAL, LOG_NEW, LOG_BIN }; +enum enum_log_type { LOG_CLOSED, LOG_TO_BE_OPENED, LOG_NORMAL, LOG_NEW, LOG_BIN}; enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON, DELAY_KEY_WRITE_ALL }; -// log info errors +/* log info errors */ #define LOG_INFO_EOF -1 #define LOG_INFO_IO -2 #define LOG_INFO_INVALID -3 @@ -43,6 +43,11 @@ enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON, #define LOG_INFO_FATAL -7 #define LOG_INFO_IN_USE -8 +/* bitmap to SQL_LOG::close() */ +#define LOG_CLOSE_INDEX 1 +#define LOG_CLOSE_TO_BE_OPENED 2 +#define LOG_CLOSE_STOP_EVENT 4 + struct st_relay_log_info; typedef struct st_log_info @@ -150,8 +155,7 @@ public: int purge_logs(THD* thd, const char* to_log); int purge_first_log(struct st_relay_log_info* rli); bool reset_logs(THD* thd); - // if we are exiting, we also want to close the index file - void close(bool exiting = 0); + void close(uint exiting); // iterating through the log index file int find_log_pos(LOG_INFO* linfo, const char* log_name,