Commit df7c1e81 authored by monty@narttu.mysql.fi's avatar monty@narttu.mysql.fi

Better fix for bug #791: At binlog rotation, INSERTs may not find their way into the binlog

parent 60c0fb7b
...@@ -14,6 +14,7 @@ slave stop; ...@@ -14,6 +14,7 @@ slave stop;
eval change master to master_host='127.0.0.1',master_user='root', eval change master to master_host='127.0.0.1',master_user='root',
master_password='',master_port=$SLAVE_MYPORT; master_password='',master_port=$SLAVE_MYPORT;
slave start; slave start;
sleep 5;
flush logs; flush logs;
sleep 5; sleep 5;
--replace_result $SLAVE_MYPORT SLAVE_PORT --replace_result $SLAVE_MYPORT SLAVE_PORT
......
...@@ -109,7 +109,7 @@ void MYSQL_LOG::cleanup() ...@@ -109,7 +109,7 @@ void MYSQL_LOG::cleanup()
if (inited) if (inited)
{ {
inited= 0; inited= 0;
close(1); close(LOG_CLOSE_INDEX);
(void) pthread_mutex_destroy(&LOCK_log); (void) pthread_mutex_destroy(&LOCK_log);
(void) pthread_mutex_destroy(&LOCK_index); (void) pthread_mutex_destroy(&LOCK_index);
(void) pthread_cond_destroy(&update_cond); (void) pthread_cond_destroy(&update_cond);
...@@ -315,6 +315,7 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, ...@@ -315,6 +315,7 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
break; break;
} }
case LOG_CLOSED: // Impossible case LOG_CLOSED: // Impossible
case LOG_TO_BE_OPENED:
DBUG_ASSERT(1); DBUG_ASSERT(1);
break; break;
} }
...@@ -332,7 +333,7 @@ shutdown the MySQL server and restart it.", log_name, errno); ...@@ -332,7 +333,7 @@ shutdown the MySQL server and restart it.", log_name, errno);
end_io_cache(&log_file); end_io_cache(&log_file);
end_io_cache(&index_file); end_io_cache(&index_file);
safeFree(name); safeFree(name);
log_type=LOG_CLOSED; log_type= LOG_CLOSED;
DBUG_RETURN(1); DBUG_RETURN(1);
} }
...@@ -565,7 +566,7 @@ bool MYSQL_LOG::reset_logs(THD* thd) ...@@ -565,7 +566,7 @@ bool MYSQL_LOG::reset_logs(THD* thd)
save_name=name; save_name=name;
name=0; // Protect against free name=0; // Protect against free
save_log_type=log_type; 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 */ /* First delete all old log files */
...@@ -583,7 +584,7 @@ bool MYSQL_LOG::reset_logs(THD* thd) ...@@ -583,7 +584,7 @@ bool MYSQL_LOG::reset_logs(THD* thd)
} }
/* Start logging with a new file */ /* 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) my_delete(index_file_name, MYF(MY_WME)); // Reset (open will update)
if (!thd->slave_thread) if (!thd->slave_thread)
need_start_event=1; need_start_event=1;
...@@ -865,7 +866,7 @@ void MYSQL_LOG::new_file(bool need_lock) ...@@ -865,7 +866,7 @@ void MYSQL_LOG::new_file(bool need_lock)
old_name=name; old_name=name;
save_log_type=log_type; save_log_type=log_type;
name=0; // Don't free name 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()). 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) ...@@ -1528,24 +1529,25 @@ void MYSQL_LOG:: wait_for_update(THD* thd)
SYNOPSIS SYNOPSIS
close() close()
exiting Set to 1 if we should also close the index file exiting Bitmask for one or more of the following bits:
This can be set to 0 if we are going to do call open LOG_CLOSE_INDEX if we should close the index file
at once after close, in which case we don't want to LOG_CLOSE_TO_BE_OPENED if we intend to call open
close the index file. at once after close.
We only write a 'stop' event to the log if exiting is set LOG_CLOSE_STOP_EVENT write a 'stop' event to the log
NOTES NOTES
One can do an open on the object at once after doing a close. One can do an open on the object at once after doing a close.
The internal structures are not freed until cleanup() is called 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! { // One can't set log_type here!
DBUG_ENTER("MYSQL_LOG::close"); DBUG_ENTER("MYSQL_LOG::close");
DBUG_PRINT("enter",("exiting: %d", (int) exiting)); DBUG_PRINT("enter",("exiting: %d", (int) exiting));
if (is_open()) 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; Stop_log_event s;
s.set_log_pos(this); s.set_log_pos(this);
...@@ -1565,7 +1567,7 @@ void MYSQL_LOG::close(bool exiting) ...@@ -1565,7 +1567,7 @@ void MYSQL_LOG::close(bool exiting)
called a not complete close earlier and the index file is still open. 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); end_io_cache(&index_file);
if (my_close(index_file.file, MYF(0)) < 0 && ! write_error) if (my_close(index_file.file, MYF(0)) < 0 && ! write_error)
...@@ -1574,7 +1576,7 @@ void MYSQL_LOG::close(bool exiting) ...@@ -1574,7 +1576,7 @@ void MYSQL_LOG::close(bool exiting)
sql_print_error(ER(ER_ERROR_ON_WRITE), index_file_name, errno); 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); safeFree(name);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -4210,8 +4210,8 @@ static void usage(void) ...@@ -4210,8 +4210,8 @@ static void usage(void)
puts("\ puts("\
Copyright (C) 2000 MySQL AB, by Monty and others\n\ Copyright (C) 2000 MySQL AB, by Monty and others\n\
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\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\ and you are welcome to modify and redistribute it under the GPL license\n\n\
Starts the MySQL server\n"); Starts the MySQL database server\n");
printf("Usage: %s [OPTIONS]\n", my_progname); printf("Usage: %s [OPTIONS]\n", my_progname);
#ifdef __WIN__ #ifdef __WIN__
......
...@@ -1314,7 +1314,7 @@ file '%s')", fname); ...@@ -1314,7 +1314,7 @@ file '%s')", fname);
if (info_fd >= 0) if (info_fd >= 0)
my_close(info_fd, MYF(0)); my_close(info_fd, MYF(0));
rli->info_fd= -1; 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); pthread_mutex_unlock(&rli->data_lock);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
...@@ -1374,7 +1374,7 @@ relay_log_pos=%s", rli->relay_log_name, llstr(rli->relay_log_pos, llbuf)); ...@@ -1374,7 +1374,7 @@ relay_log_pos=%s", rli->relay_log_name, llstr(rli->relay_log_pos, llbuf));
if (info_fd >= 0) if (info_fd >= 0)
my_close(info_fd, MYF(0)); my_close(info_fd, MYF(0));
rli->info_fd= -1; 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); pthread_mutex_unlock(&rli->data_lock);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
...@@ -2989,7 +2989,7 @@ void end_relay_log_info(RELAY_LOG_INFO* rli) ...@@ -2989,7 +2989,7 @@ void end_relay_log_info(RELAY_LOG_INFO* rli)
rli->cur_log_fd = -1; rli->cur_log_fd = -1;
} }
rli->inited = 0; rli->inited = 0;
rli->relay_log.close(1); rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -30,11 +30,11 @@ class Slave_log_event; ...@@ -30,11 +30,11 @@ class Slave_log_event;
enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE }; enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY }; enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY };
enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_IGNORE }; 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, enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON,
DELAY_KEY_WRITE_ALL }; DELAY_KEY_WRITE_ALL };
// log info errors /* log info errors */
#define LOG_INFO_EOF -1 #define LOG_INFO_EOF -1
#define LOG_INFO_IO -2 #define LOG_INFO_IO -2
#define LOG_INFO_INVALID -3 #define LOG_INFO_INVALID -3
...@@ -43,6 +43,11 @@ enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON, ...@@ -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_FATAL -7
#define LOG_INFO_IN_USE -8 #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; struct st_relay_log_info;
typedef struct st_log_info typedef struct st_log_info
...@@ -150,8 +155,7 @@ class MYSQL_LOG ...@@ -150,8 +155,7 @@ class MYSQL_LOG
int purge_logs(THD* thd, const char* to_log); int purge_logs(THD* thd, const char* to_log);
int purge_first_log(struct st_relay_log_info* rli); int purge_first_log(struct st_relay_log_info* rli);
bool reset_logs(THD* thd); bool reset_logs(THD* thd);
// if we are exiting, we also want to close the index file void close(uint exiting);
void close(bool exiting = 0);
// iterating through the log index file // iterating through the log index file
int find_log_pos(LOG_INFO* linfo, const char* log_name, int find_log_pos(LOG_INFO* linfo, const char* log_name,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment