diff options
-rw-r--r-- | sql/log.cc | 219 | ||||
-rw-r--r-- | sql/mysql_priv.h | 5 | ||||
-rw-r--r-- | sql/mysqld.cc | 72 | ||||
-rw-r--r-- | sql/slave.cc | 135 | ||||
-rw-r--r-- | sql/slave.h | 19 | ||||
-rw-r--r-- | sql/sql_class.h | 26 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 2 |
7 files changed, 252 insertions, 226 deletions
diff --git a/sql/log.cc b/sql/log.cc index 7e629ffc97f..4f9dfb1ebf0 100644 --- a/sql/log.cc +++ b/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 */ diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f2e1862ef3e..edcf12c718b 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -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(); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 24ca493deb1..41a0e5fe496 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -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) { diff --git a/sql/slave.cc b/sql/slave.cc index 9ddbe7d05de..1f28eec16fc 100644 --- a/sql/slave.cc +++ b/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); /* diff --git a/sql/slave.h b/sql/slave.h index 69d3dc38e78..c19354b2e7f 100644 --- a/sql/slave.h +++ b/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); diff --git a/sql/sql_class.h b/sql/sql_class.h index 93c27df0515..3b767e11236 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -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); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 5579d6f153d..bb8ed4eb3ca 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -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 {} |