mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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: Add timer to avoid problem when 'flush logs' is executed before we have read all data from master sql/log.cc: Better fix for bug #791: Mark log as LOG_TO_BE_OPENED instead of LOG_CLOSED when it's closed and opened. sql/mysqld.cc: Better startup message sql/slave.cc: Fix argument to close() sql/sql_class.h: Better handling of log.close()
This commit is contained in:
@ -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
|
||||||
|
30
sql/log.cc
30
sql/log.cc
@ -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,
|
|||||||
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);
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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);
|
|||||||
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 @@ err:
|
|||||||
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)
|
|||||||
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;
|
|||||||
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,
|
|||||||
#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 @@ public:
|
|||||||
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,
|
||||||
|
Reference in New Issue
Block a user