Commit be255d65 authored by unknown's avatar unknown

open binlog index file *before* tc_log->open() and binlog itself *after*


sql/mysql_priv.h:
  checkpoint: open_log() removed
sql/sql_yacc.yy:
  checkpoint: open_log() removed
sql/log.cc:
  split the opening of the .index file and binlog itself - now they are done by separate functions
sql/slave.cc:
  init_relay_log_info() made static
  split the opening of the .index file and binlog itself - now they are done by separate functions
sql/slave.h:
  init_relay_log_info() made static
sql/sql_class.h:
  split the opening of the .index file and binlog itself - now they are done by separate functions
parent 24e1d1c8
......@@ -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,18 +497,19 @@ 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,
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;
......@@ -455,7 +517,10 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
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))
......@@ -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)
{
/*
......@@ -644,11 +680,9 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
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,7 +941,8 @@ 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));
......@@ -1320,8 +1355,8 @@ void MYSQL_LOG::new_file(bool need_lock)
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:
......@@ -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 @@ int TC_LOG_MMAP::recover()
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)))
{
if (error != LOG_INFO_EOF)
sql_print_error("find_log_pos() failed (error: %d)", error);
goto err; // er ? where's the current entry ?
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();
......
......@@ -2293,41 +2293,10 @@ 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
......@@ -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)
{
......
......@@ -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;
......@@ -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,17 +1690,26 @@ 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).
*/
{
char buf[FN_REFLEN];
const char *ln;
ln= rli->relay_log.generate_name(opt_relay_logname, "-relay-bin",
1, buf);
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))
/*
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 */
if (access(fname,F_OK))
......@@ -2176,7 +2173,7 @@ 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);
......
......@@ -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);
......
......@@ -272,11 +272,29 @@ class MYSQL_LOG: public TC_LOG
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,...);
......
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