mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
open binlog index file *before* tc_log->open() and binlog itself *after*
This commit is contained in:
parent
a1690b46f2
commit
fb78bfebe4
7 changed files with 252 additions and 226 deletions
219
sql/log.cc
219
sql/log.cc
|
@ -380,7 +380,7 @@ void MYSQL_LOG::cleanup()
|
|||
|
||||
|
||||
int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
|
||||
{
|
||||
{
|
||||
fn_format(new_name,log_name,mysql_data_home,"",4);
|
||||
if (log_type != LOG_NORMAL)
|
||||
{
|
||||
|
@ -421,6 +421,67 @@ void MYSQL_LOG::init_pthread_objects()
|
|||
(void) pthread_cond_init(&update_cond, 0);
|
||||
}
|
||||
|
||||
const char *MYSQL_LOG::generate_name(const char *log_name,
|
||||
const char *suffix,
|
||||
bool strip_ext, char *buff)
|
||||
{
|
||||
DBUG_ASSERT(!strip_ext || (log_name && log_name[0]));
|
||||
if (!log_name || !log_name[0])
|
||||
{
|
||||
/*
|
||||
TODO: The following should be using fn_format(); We just need to
|
||||
first change fn_format() to cut the file name if it's too long.
|
||||
*/
|
||||
strmake(buff,glob_hostname,FN_REFLEN-5);
|
||||
strmov(fn_ext(buff),suffix);
|
||||
return (const char *)buff;
|
||||
}
|
||||
// get rid of extension if the log is binary to avoid problems
|
||||
if (strip_ext)
|
||||
{
|
||||
char *p = fn_ext(log_name);
|
||||
uint length=(uint) (p-log_name);
|
||||
strmake(buff,log_name,min(length,FN_REFLEN));
|
||||
return (const char*)buff;
|
||||
}
|
||||
return log_name;
|
||||
}
|
||||
|
||||
bool MYSQL_LOG::open_index_file(const char *index_file_name_arg,
|
||||
const char *log_name)
|
||||
{
|
||||
File index_file_nr= -1;
|
||||
DBUG_ASSERT(!my_b_inited(&index_file));
|
||||
|
||||
/*
|
||||
First open of this class instance
|
||||
Create an index file that will hold all file names uses for logging.
|
||||
Add new entries to the end of it.
|
||||
*/
|
||||
myf opt= MY_UNPACK_FILENAME;
|
||||
if (!index_file_name_arg)
|
||||
{
|
||||
index_file_name_arg= log_name; // Use same basename for index file
|
||||
opt= MY_UNPACK_FILENAME | MY_REPLACE_EXT;
|
||||
}
|
||||
fn_format(index_file_name, index_file_name_arg, mysql_data_home,
|
||||
".index", opt);
|
||||
if ((index_file_nr= my_open(index_file_name,
|
||||
O_RDWR | O_CREAT | O_BINARY ,
|
||||
MYF(MY_WME))) < 0 ||
|
||||
my_sync(index_file_nr, MYF(MY_WME)) ||
|
||||
init_io_cache(&index_file, index_file_nr,
|
||||
IO_SIZE, WRITE_CACHE,
|
||||
my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)),
|
||||
0, MYF(MY_WME)))
|
||||
{
|
||||
if (index_file_nr >= 0)
|
||||
my_close(index_file_nr,MYF(0));
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Open a (new) log file.
|
||||
|
@ -436,31 +497,35 @@ void MYSQL_LOG::init_pthread_objects()
|
|||
1 error
|
||||
*/
|
||||
|
||||
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,
|
||||
bool MYSQL_LOG::open(const char *log_name,
|
||||
enum_log_type log_type_arg,
|
||||
const char *new_name,
|
||||
enum cache_type io_cache_type_arg,
|
||||
bool no_auto_events_arg,
|
||||
ulong max_size_arg,
|
||||
bool null_created_arg)
|
||||
{
|
||||
char buff[512];
|
||||
File file= -1, index_file_nr= -1;
|
||||
char buff[FN_REFLEN];
|
||||
File file= -1;
|
||||
int open_flags = O_CREAT | O_BINARY;
|
||||
DBUG_ENTER("MYSQL_LOG::open");
|
||||
DBUG_PRINT("enter",("log_type: %d",(int) log_type));
|
||||
DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg));
|
||||
|
||||
last_time=query_start=0;
|
||||
write_error=0;
|
||||
|
||||
init(log_type_arg,io_cache_type_arg,no_auto_events_arg,max_size_arg);
|
||||
|
||||
|
||||
if (!(name=my_strdup(log_name,MYF(MY_WME))))
|
||||
{
|
||||
name= (char *)log_name; // for the error message
|
||||
goto err;
|
||||
}
|
||||
if (new_name)
|
||||
strmov(log_file_name,new_name);
|
||||
else if (generate_new_name(log_file_name, name))
|
||||
goto err;
|
||||
|
||||
|
||||
if (io_cache_type == SEQ_READ_APPEND)
|
||||
open_flags |= O_RDWR | O_APPEND;
|
||||
else
|
||||
|
@ -521,13 +586,6 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
|
|||
{
|
||||
bool write_file_name_to_index_file=0;
|
||||
|
||||
myf opt= MY_UNPACK_FILENAME;
|
||||
if (!index_file_name_arg)
|
||||
{
|
||||
index_file_name_arg= name; // Use same basename for index file
|
||||
opt= MY_UNPACK_FILENAME | MY_REPLACE_EXT;
|
||||
}
|
||||
|
||||
if (!my_b_filelength(&log_file))
|
||||
{
|
||||
/*
|
||||
|
@ -543,31 +601,9 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
|
|||
write_file_name_to_index_file= 1;
|
||||
}
|
||||
|
||||
if (!my_b_inited(&index_file))
|
||||
{
|
||||
/*
|
||||
First open of this class instance
|
||||
Create an index file that will hold all file names uses for logging.
|
||||
Add new entries to the end of it.
|
||||
*/
|
||||
fn_format(index_file_name, index_file_name_arg, mysql_data_home,
|
||||
".index", opt);
|
||||
if ((index_file_nr= my_open(index_file_name,
|
||||
O_RDWR | O_CREAT | O_BINARY ,
|
||||
MYF(MY_WME))) < 0 ||
|
||||
my_sync(index_file_nr, MYF(MY_WME)) ||
|
||||
init_io_cache(&index_file, index_file_nr,
|
||||
IO_SIZE, WRITE_CACHE,
|
||||
my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)),
|
||||
0, MYF(MY_WME)))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
safe_mutex_assert_owner(&LOCK_index);
|
||||
reinit_io_cache(&index_file, WRITE_CACHE, my_b_filelength(&index_file),
|
||||
0, 0);
|
||||
}
|
||||
DBUG_ASSERT(my_b_inited(&index_file));
|
||||
reinit_io_cache(&index_file, WRITE_CACHE,
|
||||
my_b_filelength(&index_file), 0, 0);
|
||||
if (need_start_event && !no_auto_events)
|
||||
{
|
||||
/*
|
||||
|
@ -609,7 +645,7 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
|
|||
description_event_for_queue->created= 0;
|
||||
/* Don't set log_pos in event header */
|
||||
description_event_for_queue->artificial_event=1;
|
||||
|
||||
|
||||
if (description_event_for_queue->write(&log_file))
|
||||
goto err;
|
||||
bytes_written+= description_event_for_queue->data_written;
|
||||
|
@ -644,11 +680,9 @@ err:
|
|||
sql_print_error("Could not use %s for logging (error %d). \
|
||||
Turning logging off for the whole duration of the MySQL server process. \
|
||||
To turn it on again: fix the cause, \
|
||||
shutdown the MySQL server and restart it.", log_name, errno);
|
||||
shutdown the MySQL server and restart it.", name, errno);
|
||||
if (file >= 0)
|
||||
my_close(file,MYF(0));
|
||||
if (index_file_nr >= 0)
|
||||
my_close(index_file_nr,MYF(0));
|
||||
end_io_cache(&log_file);
|
||||
end_io_cache(&index_file);
|
||||
safeFree(name);
|
||||
|
@ -754,8 +788,8 @@ int MYSQL_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
|
|||
DBUG_PRINT("enter",("log_name: %s", log_name ? log_name : "NULL"));
|
||||
|
||||
/*
|
||||
Mutex needed because we need to make sure the file pointer does not move
|
||||
from under our feet
|
||||
Mutex needed because we need to make sure the file pointer does not
|
||||
move from under our feet
|
||||
*/
|
||||
if (need_lock)
|
||||
pthread_mutex_lock(&LOCK_index);
|
||||
|
@ -907,11 +941,12 @@ bool MYSQL_LOG::reset_logs(THD* thd)
|
|||
my_delete(index_file_name, MYF(MY_WME)); // Reset (open will update)
|
||||
if (!thd->slave_thread)
|
||||
need_start_event=1;
|
||||
open(save_name, save_log_type, 0, index_file_name,
|
||||
open_index_file(index_file_name, 0);
|
||||
open(save_name, save_log_type, 0,
|
||||
io_cache_type, no_auto_events, max_size, 0);
|
||||
my_free((gptr) save_name, MYF(0));
|
||||
|
||||
err:
|
||||
err:
|
||||
pthread_mutex_unlock(&LOCK_index);
|
||||
pthread_mutex_unlock(&LOCK_log);
|
||||
DBUG_RETURN(error);
|
||||
|
@ -930,7 +965,7 @@ err:
|
|||
rli->group_relay_log_name are deleted ; if true, the latter is
|
||||
deleted too (i.e. all relay logs
|
||||
read by the SQL slave thread are deleted).
|
||||
|
||||
|
||||
NOTE
|
||||
- This is only called from the slave-execute thread when it has read
|
||||
all commands from a relay log and want to switch to a new relay log.
|
||||
|
@ -1281,7 +1316,7 @@ void MYSQL_LOG::new_file(bool need_lock)
|
|||
if (generate_new_name(new_name, name))
|
||||
goto end;
|
||||
new_name_ptr=new_name;
|
||||
|
||||
|
||||
if (log_type == LOG_BIN)
|
||||
{
|
||||
if (!no_auto_events)
|
||||
|
@ -1300,28 +1335,28 @@ void MYSQL_LOG::new_file(bool need_lock)
|
|||
log rotation should give the waiting thread a signal to
|
||||
discover EOF and move on to the next log.
|
||||
*/
|
||||
signal_update();
|
||||
signal_update();
|
||||
}
|
||||
old_name=name;
|
||||
save_log_type=log_type;
|
||||
name=0; // Don't free name
|
||||
close(LOG_CLOSE_TO_BE_OPENED);
|
||||
|
||||
/*
|
||||
/*
|
||||
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).
|
||||
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, 1);
|
||||
open(old_name, save_log_type, new_name_ptr,
|
||||
io_cache_type, no_auto_events, max_size, 1);
|
||||
my_free(old_name,MYF(0));
|
||||
|
||||
end:
|
||||
|
@ -2028,11 +2063,11 @@ void MYSQL_LOG::wait_for_update(THD* thd, bool master_or_slave)
|
|||
|
||||
SYNOPSIS
|
||||
close()
|
||||
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
|
||||
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.
|
||||
|
@ -2433,7 +2468,7 @@ int TC_LOG_MMAP::open(const char *opt_name)
|
|||
bool crashed=FALSE;
|
||||
PAGE *pg;
|
||||
|
||||
DBUG_ASSERT(total_ha_2pc);
|
||||
DBUG_ASSERT(total_ha_2pc > 1);
|
||||
DBUG_ASSERT(opt_name && opt_name[0]);
|
||||
|
||||
#ifdef HAVE_GETPAGESIZE
|
||||
|
@ -2824,6 +2859,18 @@ err1:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Perform heuristic recovery, if --tc-heuristic-recover was used
|
||||
|
||||
RETURN VALUE
|
||||
0 no heuristic recovery was requested
|
||||
1 heuristic recovery was performed
|
||||
|
||||
NOTE
|
||||
no matter whether heuristic recovery was successful or not
|
||||
mysqld must exit. So, return value is the same in both cases.
|
||||
*/
|
||||
|
||||
int TC_LOG::using_heuristic_recover()
|
||||
{
|
||||
if (!tc_heuristic_recover)
|
||||
|
@ -2848,10 +2895,11 @@ int TC_LOG::using_heuristic_recover()
|
|||
|
||||
int TC_LOG_BINLOG::open(const char *opt_name)
|
||||
{
|
||||
LOG_INFO log_info, new_log_info;
|
||||
int error;
|
||||
LOG_INFO log_info;
|
||||
int error= 1;
|
||||
|
||||
DBUG_ASSERT(total_ha_2pc > 1);
|
||||
DBUG_ASSERT(opt_name && opt_name[0]);
|
||||
|
||||
pthread_mutex_init(&LOCK_prep_xids, MY_MUTEX_INIT_FAST);
|
||||
pthread_cond_init (&COND_prep_xids, 0);
|
||||
|
@ -2859,21 +2907,15 @@ int TC_LOG_BINLOG::open(const char *opt_name)
|
|||
if (using_heuristic_recover())
|
||||
return 1;
|
||||
|
||||
/*
|
||||
read index file to get a last but one binlog filename
|
||||
note - there's no need to lock any mutex, mysqld is only starting
|
||||
up, no other threads are running yet.
|
||||
still, there's safe_mutex_assert_owner() in binlog code, so
|
||||
let's keep it happy.
|
||||
*/
|
||||
|
||||
if ((error= find_log_pos(&new_log_info, NullS, 1)))
|
||||
if ((error= find_log_pos(&log_info, NullS, 1)))
|
||||
{
|
||||
sql_print_error("find_log_pos() failed (error: %d)", error);
|
||||
goto err; // er ? where's the current entry ?
|
||||
if (error != LOG_INFO_EOF)
|
||||
sql_print_error("find_log_pos() failed (error: %d)", error);
|
||||
else
|
||||
error= 0;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (strcmp(log_file_name, new_log_info.log_file_name))
|
||||
{
|
||||
const char *errmsg;
|
||||
char last_event_type=UNKNOWN_EVENT;
|
||||
|
@ -2881,23 +2923,22 @@ int TC_LOG_BINLOG::open(const char *opt_name)
|
|||
File file;
|
||||
Log_event *ev=0;
|
||||
Format_description_log_event fdle(BINLOG_VERSION);
|
||||
char log_name[FN_REFLEN];
|
||||
|
||||
if (! fdle.is_valid())
|
||||
goto err;
|
||||
|
||||
do
|
||||
for (error= 0; !error ;)
|
||||
{
|
||||
log_info.index_file_offset=new_log_info.index_file_offset;
|
||||
log_info.index_file_start_offset=new_log_info.index_file_offset;
|
||||
strcpy(log_info.log_file_name, new_log_info.log_file_name);
|
||||
if ((error= find_next_log(&new_log_info, 1)))
|
||||
strnmov(log_name, log_info.log_file_name, sizeof(log_name));
|
||||
if ((error= find_next_log(&log_info, 1)) != LOG_INFO_EOF)
|
||||
{
|
||||
sql_print_error("find_log_pos() failed (error: %d)", error);
|
||||
goto err; // er ? where's the current entry ?
|
||||
goto err;
|
||||
}
|
||||
} while (strcmp(log_file_name, new_log_info.log_file_name));
|
||||
}
|
||||
|
||||
if ((file= open_binlog(&log, log_info.log_file_name, &errmsg)) < 0)
|
||||
if ((file= open_binlog(&log, log_name, &errmsg)) < 0)
|
||||
{
|
||||
sql_print_error("%s", errmsg);
|
||||
goto err;
|
||||
|
@ -2921,10 +2962,8 @@ int TC_LOG_BINLOG::open(const char *opt_name)
|
|||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return 1;
|
||||
return error;
|
||||
}
|
||||
|
||||
/* this is called on shutdown, after ha_panic */
|
||||
|
|
|
@ -930,11 +930,6 @@ void sql_print_information(const char *format, ...);
|
|||
|
||||
bool fn_format_relative_to_data_home(my_string to, const char *name,
|
||||
const char *dir, const char *extension);
|
||||
bool open_log(MYSQL_LOG *log, const char *hostname,
|
||||
const char *opt_name, const char *extension,
|
||||
const char *index_file_name,
|
||||
enum_log_type type, bool read_append,
|
||||
bool no_auto_events, ulong max_size);
|
||||
File open_binlog(IO_CACHE *log, const char *log_file_name,
|
||||
const char **errmsg);
|
||||
handlerton *binlog_init();
|
||||
|
|
|
@ -2289,45 +2289,14 @@ extern "C" pthread_handler_decl(handle_shutdown,arg)
|
|||
#endif
|
||||
|
||||
|
||||
const char *load_default_groups[]= {
|
||||
const char *load_default_groups[]= {
|
||||
#ifdef HAVE_NDBCLUSTER_DB
|
||||
"mysql_cluster",
|
||||
#endif
|
||||
"mysqld","server",MYSQL_BASE_VERSION,0,0};
|
||||
"mysqld","server", MYSQL_BASE_VERSION, 0, 0};
|
||||
static const int load_default_groups_sz=
|
||||
sizeof(load_default_groups)/sizeof(load_default_groups[0]);
|
||||
|
||||
bool open_log(MYSQL_LOG *log, const char *hostname,
|
||||
const char *opt_name, const char *extension,
|
||||
const char *index_file_name,
|
||||
enum_log_type type, bool read_append,
|
||||
bool no_auto_events, ulong max_size)
|
||||
{
|
||||
char tmp[FN_REFLEN];
|
||||
if (!opt_name || !opt_name[0])
|
||||
{
|
||||
/*
|
||||
TODO: The following should be using fn_format(); We just need to
|
||||
first change fn_format() to cut the file name if it's too long.
|
||||
*/
|
||||
strmake(tmp,hostname,FN_REFLEN-5);
|
||||
strmov(fn_ext(tmp),extension);
|
||||
opt_name=tmp;
|
||||
}
|
||||
// get rid of extension if the log is binary to avoid problems
|
||||
if (type == LOG_BIN)
|
||||
{
|
||||
char *p = fn_ext(opt_name);
|
||||
uint length=(uint) (p-opt_name);
|
||||
strmake(tmp,opt_name,min(length,FN_REFLEN));
|
||||
opt_name=tmp;
|
||||
}
|
||||
return log->open(opt_name, type, 0, index_file_name,
|
||||
(read_append) ? SEQ_READ_APPEND : WRITE_CACHE,
|
||||
no_auto_events, max_size, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Initialize one of the global date/time format variables
|
||||
|
||||
|
@ -2335,7 +2304,7 @@ bool open_log(MYSQL_LOG *log, const char *hostname,
|
|||
init_global_datetime_format()
|
||||
format_type What kind of format should be supported
|
||||
var_ptr Pointer to variable that should be updated
|
||||
|
||||
|
||||
NOTES
|
||||
The default value is taken from either opt_date_time_formats[] or
|
||||
the ISO format (ANSI SQL)
|
||||
|
@ -2617,8 +2586,7 @@ static int init_server_components()
|
|||
#endif
|
||||
/* Setup log files */
|
||||
if (opt_log)
|
||||
open_log(&mysql_log, glob_hostname, opt_logname, ".log", NullS,
|
||||
LOG_NORMAL, 0, 0, 0);
|
||||
mysql_log.open_query_log(opt_logname);
|
||||
if (opt_update_log)
|
||||
{
|
||||
/*
|
||||
|
@ -2671,20 +2639,13 @@ version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
|
|||
with --log-bin instead.");
|
||||
}
|
||||
}
|
||||
if (opt_bin_log)
|
||||
{
|
||||
open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
|
||||
opt_binlog_index_name, LOG_BIN, 0, 0, max_binlog_size);
|
||||
using_update_log=1;
|
||||
}
|
||||
else if (opt_log_slave_updates)
|
||||
if (opt_log_slave_updates && !opt_bin_log)
|
||||
sql_print_warning("\
|
||||
you need to use --log-bin to make --log-slave-updates work. \
|
||||
You need to use --log-bin to make --log-slave-updates work. \
|
||||
Now disabling --log-slave-updates.");
|
||||
|
||||
if (opt_slow_log)
|
||||
open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log",
|
||||
NullS, LOG_NORMAL, 0, 0, 0);
|
||||
mysql_slow_log.open_slow_log(opt_slow_logname);
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
if (opt_log_slave_updates && replicate_same_server_id)
|
||||
|
@ -2716,12 +2677,25 @@ server.");
|
|||
}
|
||||
}
|
||||
|
||||
if (opt_bin_log)
|
||||
{
|
||||
char buf[FN_REFLEN];
|
||||
const char *ln;
|
||||
ln= mysql_bin_log.generate_name(opt_bin_logname, "-bin", 1, buf);
|
||||
if (ln == buf)
|
||||
{
|
||||
my_free(opt_bin_logname, MYF(0));
|
||||
opt_bin_logname=my_strdup(buf, MYF(0));
|
||||
}
|
||||
mysql_bin_log.open_index_file(opt_binlog_index_name, ln);
|
||||
using_update_log=1;
|
||||
}
|
||||
|
||||
if (ha_init())
|
||||
{
|
||||
sql_print_error("Can't init databases");
|
||||
unireg_abort(1);
|
||||
}
|
||||
|
||||
tc_log= total_ha_2pc > 1 ? opt_bin_log ?
|
||||
(TC_LOG *)&mysql_bin_log :
|
||||
(TC_LOG *)&tc_log_mmap :
|
||||
|
@ -2733,6 +2707,10 @@ server.");
|
|||
unireg_abort(1);
|
||||
}
|
||||
|
||||
if (opt_bin_log)
|
||||
mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
|
||||
WRITE_CACHE, 0, max_binlog_size, 0);
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
if (opt_bin_log && expire_logs_days)
|
||||
{
|
||||
|
|
135
sql/slave.cc
135
sql/slave.cc
|
@ -1,15 +1,15 @@
|
|||
/* Copyright (C) 2000-2003 MySQL AB
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
@ -158,7 +158,7 @@ int init_slave()
|
|||
sql_print_error("Failed to allocate memory for the master info structure");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
if (init_master_info(active_mi,master_info_file,relay_log_info_file,
|
||||
!master_host, (SLAVE_IO | SLAVE_SQL)))
|
||||
{
|
||||
|
@ -551,9 +551,9 @@ int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset,
|
|||
/*
|
||||
Even if rli->inited==0, we still try to empty rli->master_log_* variables.
|
||||
Indeed, rli->inited==0 does not imply that they already are empty.
|
||||
It could be that slave's info initialization partly succeeded :
|
||||
It could be that slave's info initialization partly succeeded :
|
||||
for example if relay-log.info existed but *relay-bin*.*
|
||||
have been manually removed, init_relay_log_info reads the old
|
||||
have been manually removed, init_relay_log_info reads the old
|
||||
relay-log.info and fills rli->master_log_*, then init_relay_log_info
|
||||
checks for the existence of the relay log, this fails and
|
||||
init_relay_log_info leaves rli->inited to 0.
|
||||
|
@ -562,7 +562,7 @@ int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset,
|
|||
MASTER, the callers of purge_relay_logs, will delete bogus *.info files
|
||||
or replace them with correct files), however if the user does SHOW SLAVE
|
||||
STATUS before START SLAVE, he will see old, confusing rli->master_log_*.
|
||||
In other words, we reinit rli->master_log_* for SHOW SLAVE STATUS
|
||||
In other words, we reinit rli->master_log_* for SHOW SLAVE STATUS
|
||||
to display fine in any case.
|
||||
*/
|
||||
|
||||
|
@ -1655,7 +1655,8 @@ void end_master_info(MASTER_INFO* mi)
|
|||
}
|
||||
|
||||
|
||||
int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname)
|
||||
static int init_relay_log_info(RELAY_LOG_INFO* rli,
|
||||
const char* info_fname)
|
||||
{
|
||||
char fname[FN_REFLEN+128];
|
||||
int info_fd;
|
||||
|
@ -1663,7 +1664,7 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname)
|
|||
int error = 0;
|
||||
DBUG_ENTER("init_relay_log_info");
|
||||
|
||||
if (rli->inited) // Set if this function called
|
||||
if (rli->inited) // Set if this function called
|
||||
DBUG_RETURN(0);
|
||||
fn_format(fname, info_fname, mysql_data_home, "", 4+32);
|
||||
pthread_mutex_lock(&rli->data_lock);
|
||||
|
@ -1674,23 +1675,10 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname)
|
|||
rli->log_space_limit= relay_log_space_limit;
|
||||
rli->log_space_total= 0;
|
||||
|
||||
// TODO: make this work with multi-master
|
||||
if (!opt_relay_logname)
|
||||
{
|
||||
char tmp[FN_REFLEN];
|
||||
/*
|
||||
TODO: The following should be using fn_format(); We just need to
|
||||
first change fn_format() to cut the file name if it's too long.
|
||||
*/
|
||||
strmake(tmp,glob_hostname,FN_REFLEN-5);
|
||||
strmov(strcend(tmp,'.'),"-relay-bin");
|
||||
opt_relay_logname=my_strdup(tmp,MYF(MY_WME));
|
||||
}
|
||||
|
||||
/*
|
||||
The relay log will now be opened, as a SEQ_READ_APPEND IO_CACHE.
|
||||
Note that the I/O thread flushes it to disk after writing every event, in
|
||||
flush_master_info(mi, 1).
|
||||
Note that the I/O thread flushes it to disk after writing every
|
||||
event, in flush_master_info(mi, 1).
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -1702,16 +1690,25 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname)
|
|||
switch to using max_binlog_size for the relay log) and update
|
||||
rli->relay_log.max_size (and mysql_bin_log.max_size).
|
||||
*/
|
||||
|
||||
if (open_log(&rli->relay_log, glob_hostname, opt_relay_logname,
|
||||
"-relay-bin", opt_relaylog_index_name,
|
||||
LOG_BIN, 1 /* read_append cache */,
|
||||
0 /* starting from 5.0 we want relay logs to have auto events */,
|
||||
max_relay_log_size ? max_relay_log_size : max_binlog_size))
|
||||
{
|
||||
pthread_mutex_unlock(&rli->data_lock);
|
||||
sql_print_error("Failed in open_log() called from init_relay_log_info()");
|
||||
DBUG_RETURN(1);
|
||||
char buf[FN_REFLEN];
|
||||
const char *ln;
|
||||
ln= rli->relay_log.generate_name(opt_relay_logname, "-relay-bin",
|
||||
1, buf);
|
||||
|
||||
/*
|
||||
note, that if open() fails, we'll still have index file open
|
||||
but a destructor will take care of that
|
||||
*/
|
||||
if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln) ||
|
||||
rli->relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, 0,
|
||||
(max_relay_log_size ? max_relay_log_size :
|
||||
max_binlog_size), 0))
|
||||
{
|
||||
pthread_mutex_unlock(&rli->data_lock);
|
||||
sql_print_error("Failed in open_log() called from init_relay_log_info()");
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* if file does not exist */
|
||||
|
@ -1980,9 +1977,9 @@ void clear_until_condition(RELAY_LOG_INFO* rli)
|
|||
|
||||
|
||||
int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
|
||||
const char* slave_info_fname,
|
||||
bool abort_if_no_master_info_file,
|
||||
int thread_mask)
|
||||
const char* slave_info_fname,
|
||||
bool abort_if_no_master_info_file,
|
||||
int thread_mask)
|
||||
{
|
||||
int fd,error;
|
||||
char fname[FN_REFLEN+128];
|
||||
|
@ -1996,7 +1993,7 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
|
|||
last time. If this case pos_in_file would be set and we would
|
||||
get a crash when trying to read the signature for the binary
|
||||
relay log.
|
||||
|
||||
|
||||
We only rewind the read position if we are starting the SQL
|
||||
thread. The handle_slave_sql thread assumes that the read
|
||||
position is at the beginning of the file, and will read the
|
||||
|
@ -2022,7 +2019,7 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
|
|||
fd = mi->fd;
|
||||
|
||||
/* does master.info exist ? */
|
||||
|
||||
|
||||
if (access(fname,F_OK))
|
||||
{
|
||||
if (abort_if_no_master_info_file)
|
||||
|
@ -2058,7 +2055,7 @@ file '%s')", fname);
|
|||
{
|
||||
if (fd >= 0)
|
||||
reinit_io_cache(&mi->file, READ_CACHE, 0L,0,0);
|
||||
else
|
||||
else
|
||||
{
|
||||
if ((fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0 )
|
||||
{
|
||||
|
@ -2078,52 +2075,52 @@ file '%s')", fname);
|
|||
mi->fd = fd;
|
||||
int port, connect_retry, master_log_pos, ssl= 0, lines;
|
||||
char *first_non_digit;
|
||||
|
||||
|
||||
/*
|
||||
Starting from 4.1.x master.info has new format. Now its
|
||||
first line contains number of lines in file. By reading this
|
||||
number we will be always distinguish to which version our
|
||||
master.info corresponds to. We can't simply count lines in
|
||||
first line contains number of lines in file. By reading this
|
||||
number we will be always distinguish to which version our
|
||||
master.info corresponds to. We can't simply count lines in
|
||||
file since versions before 4.1.x could generate files with more
|
||||
lines than needed.
|
||||
If first line doesn't contain a number or contain number less than
|
||||
If first line doesn't contain a number or contain number less than
|
||||
14 then such file is treated like file from pre 4.1.1 version.
|
||||
There is no ambiguity when reading an old master.info, as before
|
||||
There is no ambiguity when reading an old master.info, as before
|
||||
4.1.1, the first line contained the binlog's name, which is either
|
||||
empty or has an extension (contains a '.'), so can't be confused
|
||||
empty or has an extension (contains a '.'), so can't be confused
|
||||
with an integer.
|
||||
|
||||
So we're just reading first line and trying to figure which version
|
||||
So we're just reading first line and trying to figure which version
|
||||
is this.
|
||||
*/
|
||||
|
||||
/*
|
||||
The first row is temporarily stored in mi->master_log_name,
|
||||
if it is line count and not binlog name (new format) it will be
|
||||
|
||||
/*
|
||||
The first row is temporarily stored in mi->master_log_name,
|
||||
if it is line count and not binlog name (new format) it will be
|
||||
overwritten by the second row later.
|
||||
*/
|
||||
if (init_strvar_from_file(mi->master_log_name,
|
||||
sizeof(mi->master_log_name), &mi->file,
|
||||
""))
|
||||
goto errwithmsg;
|
||||
|
||||
|
||||
lines= strtoul(mi->master_log_name, &first_non_digit, 10);
|
||||
|
||||
if (mi->master_log_name[0]!='\0' &&
|
||||
if (mi->master_log_name[0]!='\0' &&
|
||||
*first_non_digit=='\0' && lines >= LINES_IN_MASTER_INFO_WITH_SSL)
|
||||
{ // Seems to be new format
|
||||
if (init_strvar_from_file(mi->master_log_name,
|
||||
if (init_strvar_from_file(mi->master_log_name,
|
||||
sizeof(mi->master_log_name), &mi->file, ""))
|
||||
goto errwithmsg;
|
||||
}
|
||||
else
|
||||
lines= 7;
|
||||
|
||||
|
||||
if (init_intvar_from_file(&master_log_pos, &mi->file, 4) ||
|
||||
init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file,
|
||||
master_host) ||
|
||||
init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file,
|
||||
master_user) ||
|
||||
master_user) ||
|
||||
init_strvar_from_file(mi->password, SCRAMBLED_PASSWORD_CHAR_LENGTH+1,
|
||||
&mi->file, master_password) ||
|
||||
init_intvar_from_file(&port, &mi->file, master_port) ||
|
||||
|
@ -2131,17 +2128,17 @@ file '%s')", fname);
|
|||
master_connect_retry))
|
||||
goto errwithmsg;
|
||||
|
||||
/*
|
||||
If file has ssl part use it even if we have server without
|
||||
SSL support. But these option will be ignored later when
|
||||
slave will try connect to master, so in this case warning
|
||||
/*
|
||||
If file has ssl part use it even if we have server without
|
||||
SSL support. But these option will be ignored later when
|
||||
slave will try connect to master, so in this case warning
|
||||
is printed.
|
||||
*/
|
||||
if (lines >= LINES_IN_MASTER_INFO_WITH_SSL &&
|
||||
if (lines >= LINES_IN_MASTER_INFO_WITH_SSL &&
|
||||
(init_intvar_from_file(&ssl, &mi->file, master_ssl) ||
|
||||
init_strvar_from_file(mi->ssl_ca, sizeof(mi->ssl_ca),
|
||||
init_strvar_from_file(mi->ssl_ca, sizeof(mi->ssl_ca),
|
||||
&mi->file, master_ssl_ca) ||
|
||||
init_strvar_from_file(mi->ssl_capath, sizeof(mi->ssl_capath),
|
||||
init_strvar_from_file(mi->ssl_capath, sizeof(mi->ssl_capath),
|
||||
&mi->file, master_ssl_capath) ||
|
||||
init_strvar_from_file(mi->ssl_cert, sizeof(mi->ssl_cert),
|
||||
&mi->file, master_ssl_cert) ||
|
||||
|
@ -2156,7 +2153,7 @@ file '%s')", fname);
|
|||
"('%s') are ignored because this MySQL slave was compiled "
|
||||
"without SSL support.", fname);
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
|
||||
/*
|
||||
This has to be handled here as init_intvar_from_file can't handle
|
||||
my_off_t types
|
||||
|
@ -2176,15 +2173,15 @@ file '%s')", fname);
|
|||
|
||||
mi->inited = 1;
|
||||
// now change cache READ -> WRITE - must do this before flush_master_info
|
||||
reinit_io_cache(&mi->file, WRITE_CACHE,0L,0,1);
|
||||
reinit_io_cache(&mi->file, WRITE_CACHE, 0L, 0, 1);
|
||||
if ((error=test(flush_master_info(mi, 1))))
|
||||
sql_print_error("Failed to flush master info file");
|
||||
pthread_mutex_unlock(&mi->data_lock);
|
||||
DBUG_RETURN(error);
|
||||
|
||||
|
||||
errwithmsg:
|
||||
sql_print_error("Error reading master configuration");
|
||||
|
||||
|
||||
err:
|
||||
if (fd >= 0)
|
||||
{
|
||||
|
@ -4553,7 +4550,7 @@ Log_event* next_event(RELAY_LOG_INFO* rli)
|
|||
/* This is an assertion which sometimes fails, let's try to track it */
|
||||
char llbuf1[22], llbuf2[22];
|
||||
DBUG_PRINT("info", ("my_b_tell(cur_log)=%s rli->event_relay_log_pos=%s",
|
||||
llstr(my_b_tell(cur_log),llbuf1),
|
||||
llstr(my_b_tell(cur_log),llbuf1),
|
||||
llstr(rli->event_relay_log_pos,llbuf2)));
|
||||
DBUG_ASSERT(my_b_tell(cur_log) >= BIN_LOG_HEADER_SIZE);
|
||||
DBUG_ASSERT(my_b_tell(cur_log) == rli->event_relay_log_pos);
|
||||
|
@ -4573,7 +4570,7 @@ Log_event* next_event(RELAY_LOG_INFO* rli)
|
|||
*/
|
||||
if ((ev=Log_event::read_log_event(cur_log,0,
|
||||
rli->relay_log.description_event_for_exec)))
|
||||
|
||||
|
||||
{
|
||||
DBUG_ASSERT(thd==rli->sql_thd);
|
||||
/*
|
||||
|
|
19
sql/slave.h
19
sql/slave.h
|
@ -1,15 +1,15 @@
|
|||
/* Copyright (C) 2000-2003 MySQL AB
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
@ -366,11 +366,11 @@ typedef struct st_master_info
|
|||
my_bool ssl; // enables use of SSL connection if true
|
||||
char ssl_ca[FN_REFLEN], ssl_capath[FN_REFLEN], ssl_cert[FN_REFLEN];
|
||||
char ssl_cipher[FN_REFLEN], ssl_key[FN_REFLEN];
|
||||
|
||||
|
||||
my_off_t master_log_pos;
|
||||
File fd; // we keep the file open, so we need to remember the file pointer
|
||||
IO_CACHE file;
|
||||
|
||||
|
||||
pthread_mutex_t data_lock,run_lock;
|
||||
pthread_cond_t data_cond,start_cond,stop_cond;
|
||||
THD *io_thd;
|
||||
|
@ -385,7 +385,7 @@ typedef struct st_master_info
|
|||
bool inited;
|
||||
volatile bool abort_slave, slave_running;
|
||||
volatile ulong slave_run_id;
|
||||
/*
|
||||
/*
|
||||
The difference in seconds between the clock of the master and the clock of
|
||||
the slave (second - first). It must be signed as it may be <0 or >0.
|
||||
clock_diff_with_master is computed when the I/O thread starts; for this the
|
||||
|
@ -394,8 +394,8 @@ typedef struct st_master_info
|
|||
clock_of_slave - last_timestamp_executed_by_SQL_thread - clock_diff_with_master
|
||||
|
||||
*/
|
||||
long clock_diff_with_master;
|
||||
|
||||
long clock_diff_with_master;
|
||||
|
||||
st_master_info()
|
||||
:ssl(0), fd(-1), io_thd(0), inited(0),
|
||||
abort_slave(0),slave_running(0), slave_run_id(0)
|
||||
|
@ -403,7 +403,7 @@ typedef struct st_master_info
|
|||
host[0] = 0; user[0] = 0; password[0] = 0;
|
||||
ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0;
|
||||
ssl_cipher[0]= 0; ssl_key[0]= 0;
|
||||
|
||||
|
||||
bzero((char*) &file, sizeof(file));
|
||||
pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST);
|
||||
pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST);
|
||||
|
@ -523,7 +523,6 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
|
|||
bool abort_if_no_master_info_file,
|
||||
int thread_mask);
|
||||
void end_master_info(MASTER_INFO* mi);
|
||||
int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname);
|
||||
void end_relay_log_info(RELAY_LOG_INFO* rli);
|
||||
void lock_slave_threads(MASTER_INFO* mi);
|
||||
void unlock_slave_threads(MASTER_INFO* mi);
|
||||
|
|
|
@ -255,7 +255,7 @@ public:
|
|||
{
|
||||
#ifndef DBUG_OFF
|
||||
char buf1[22],buf2[22];
|
||||
#endif
|
||||
#endif
|
||||
DBUG_ENTER("harvest_bytes_written");
|
||||
(*counter)+=bytes_written;
|
||||
DBUG_PRINT("info",("counter: %s bytes_written: %s", llstr(*counter,buf1),
|
||||
|
@ -272,11 +272,29 @@ public:
|
|||
bool no_auto_events_arg, ulong max_size);
|
||||
void init_pthread_objects();
|
||||
void cleanup();
|
||||
bool open(const char *log_name,enum_log_type log_type,
|
||||
const char *new_name, const char *index_file_name_arg,
|
||||
bool open(const char *log_name,
|
||||
enum_log_type log_type,
|
||||
const char *new_name,
|
||||
enum cache_type io_cache_type_arg,
|
||||
bool no_auto_events_arg, ulong max_size,
|
||||
bool null_created);
|
||||
const char *generate_name(const char *log_name, const char *suffix,
|
||||
bool strip_ext, char *buff);
|
||||
/* simplified open_xxx wrappers for the gigantic open above */
|
||||
bool open_query_log(const char *log_name)
|
||||
{
|
||||
char buf[FN_REFLEN];
|
||||
return open(generate_name(log_name, ".log", 0, buf),
|
||||
LOG_NORMAL, 0, WRITE_CACHE, 0, 0, 0);
|
||||
}
|
||||
bool open_slow_log(const char *log_name)
|
||||
{
|
||||
char buf[FN_REFLEN];
|
||||
return open(generate_name(log_name, "-slow.log", 0, buf),
|
||||
LOG_NORMAL, 0, WRITE_CACHE, 0, 0, 0);
|
||||
}
|
||||
bool open_index_file(const char *index_file_name_arg,
|
||||
const char *log_name);
|
||||
void new_file(bool need_lock= 1);
|
||||
bool write(THD *thd, enum enum_server_command command,
|
||||
const char *format,...);
|
||||
|
@ -291,7 +309,7 @@ public:
|
|||
*/
|
||||
bool appendv(const char* buf,uint len,...);
|
||||
bool append(Log_event* ev);
|
||||
|
||||
|
||||
int generate_new_name(char *new_name,const char *old_name);
|
||||
void make_log_name(char* buf, const char* log_ident);
|
||||
bool is_active(const char* log_file_name);
|
||||
|
|
|
@ -8052,7 +8052,7 @@ xa: XA_SYM begin_or_start xid opt_join_or_resume
|
|||
;
|
||||
|
||||
xid: ident_or_text { Lex->ident=$1; }
|
||||
;
|
||||
;
|
||||
|
||||
begin_or_start: BEGIN_SYM {}
|
||||
| START_SYM {}
|
||||
|
|
Loading…
Reference in a new issue