Hi Luis,
Sorry I pressed send by mistake. :)
Thank you for the comments.
Find some answers in-line.
Cheers.
Alfranio Correia wrote:
>
> Luís Soares wrote:
>> Hi Alfranio,
>>
>> Nice Work. Please find my review comments below.
>>
>> STATUS
>> ------
>>
>> Not Approved.
>>
>> REQUIRED CHANGES
>> ----------------
>>
>> RC1. Please revert changes to white spaces that are not
>> meaningful, and unnecessary changes. They can cause
>> spurious merge problems.
>
> ok.
>> RC2. Why protect some parts of the code with HAVE_REPLICATION?
>> Seems these parts are probably not replication
>> specific. Please, double check and if they are not, remove
>> the guards. See comments inline.
>
> The code does not compile without the IFs.
>
>> RC3. Please, don't duplicate code. Maybe, wrap the duplicate
>> code into some private methods. See comments inline.
>
> Ok. Fixed.
>
>> RC4. Please, fix the message in some sql_print_warning. See
>> comments inline.
>
>
> Done. Most likely, you meant sql_print_error.
>
>> RC5. Should you check that return value of find_log_pos is
>> LOG_INFO_EOF ? You can get LOG_INFO_IO which does not
>> necessarily mean that no entry was found. See comments
>> inline.
>>
>>
>> REQUESTS
>> --------
>>
>> R1. The test case still seems not platform agnostic. Have you
>> run it on windows? The paths from the cat_file may cause
>> the test to fail. Perhaps to be safe mask/remove
>> those (replace_result? replace_regex ?). Maybe something
>> like:
>>
>> -- eval SET @index=LOAD_FILE('$index_file')
>> -- replace_regex /\.[\\\/]master/master/
>> SELECT @index;
>
> I will check that.
>
>> SUGGESTIONS
>> -----------
>>
>> S1. Improve some comments. See inline.
>>
>> DETAILS
>> -------
>>
>> Please find some comments inline.
>>
>> On Mon, 2009-11-23 at 03:09 +0000, Alfranio Correia wrote:
>>> #At
> file:///home/acorreia/workspace.sun/repository.mysql/bzrwork/bug-45292/mysql-5.1-bugteam/
> based on revid:li-bing.song@stripped
>>>
>>> 3215 Alfranio Correia 2009-11-23
>>> BUG#45292 orphan binary log created when starting server twice
>>>
>>> This patch fixes three bugs as follows. First, aborting the server
> while purging
>>> binary logs might generate orphan files due to how the purge operation
> was
>>> implemented:
>>>
>>> (purge routine - sql/log.cc - MYSQL_BIN_LOG::purge_logs)
>>>
>>> 1 - register the files to be removed in a temporary buffer.
>>> 2 - update the log-bin.index.
>>> 3 - flush the log-bin.index.
>>> 4 - erase the files whose names where register in the temporary
> buffer
>>> in step 1.
>>> Thus a failure while executing step 4 would generate an orphan file.
> Second,
>>> a similar issue might happen while creating a new binary as follows:
>>>
>>> (open routine - sql/log.cc - MYSQL_BIN_LOG::open)
>>>
>>> 1 - open the new log-bin.
>>> 2 - update the log-bin.index.
>>>
>>> Thus a failure while executing step 1 would generate an orphan file.
>>>
>>> To fix these issues, we record the files to be purged or created before
> really
>>> removing or adding them. So if a failure happens such registers can be
> used to
>>> automatically remove dangling files. The new steps might be outlined as
> follows:
>>>
>>> (purge routine - sql/log.cc - MYSQL_BIN_LOG::purge_logs)
>>>
>>> 1 - register the files to be removed in the log-bin.log placed
> in
>>> the data directory.
>> Suggestion: s/register/record?
>
>
> done.
>
>>> 2 - update the log-bin.index.
>>> 3 - flush the log-bin.index.
>> You are closing the "register" at the end of purge_logs, so:
>>
>> 4. close log-bin.log (and remove it)
>>
>>
>>> (open routine - sql/log.cc - MYSQL_BIN_LOG::open)
>>>
>>> 1 - register the file to be created in the log-bin.log
>>> placed in the data directory.
>>> 2 - open the new log-bin.
>>> 3 - update the log-bin.index.
>>
>> You are closing the "register" at the end of open, so:
>>
>> 4. close log-bin.log (and remove it)
>>
>>
>>>
>>> (purge routine - sql/log.cc -
> MYSQL_BIN_LOG::open_index_file)
>>>
>>> 1 - open the log-bin.index.
>>> 2 - open the log-bin.log.
>>> 3 - for each file in log-bin.log
>>> 3.1 Check if the file is in the log-bin.index and if so ignore
> it.
>>> 3.2 Otherwise, delete it.
>>>
>> You are closing the "register" in the piece of code that adds this
>> new logic in open_index_file, so:
>>
>> 4. close log-bin.log (and remove it)
>>
>>
>>> The third issue can be described as follows. The purge operation was
> allowing
>>> to remove a file in use thus leading to the loss of data and possible
>>> inconsistencies between the master and slave. Roughly, the routine was
> only
>>> taking into account the dump threads and so if a slave was not connect
> the
>>> file might be delete even though it was in use.
>>>
>>> modified:
>>> mysql-test/suite/binlog/r/binlog_index.result
>>> mysql-test/suite/binlog/t/binlog_index.test
>>> sql/log.cc
>>> sql/log.h
>>> sql/mysqld.cc
>>> sql/rpl_rli.cc
>>> === modified file 'mysql-test/suite/binlog/r/binlog_index.result'
>>> --- a/mysql-test/suite/binlog/r/binlog_index.result 2009-01-23 12:22:05
> +0000
>>> +++ b/mysql-test/suite/binlog/r/binlog_index.result 2009-11-23 03:09:52
> +0000
>>> @@ -1,3 +1,8 @@
>>> +call mtr.add_suppression('Attempting backtrace');
>>> +call mtr.add_suppression('MSYQL_LOG::purge_logs failed to process registered
> files that would be purged.');
>>> +call mtr.add_suppression('MSYQL_BIN_LOG::open failed to sync the index
> file');
>>> +call mtr.add_suppression('Turning logging off for the whole duration of the
> MySQL server process.');
>>> +call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to clean
> registers before purging logs.');
>>> flush logs;
>>> flush logs;
>>> flush logs;
>>> @@ -21,7 +26,6 @@ flush logs;
>>> *** must be a warning master-bin.000001 was not found ***
>>> Warnings:
>>> Warning 1612 Being purged log master-bin.000001 was not found
>>> -Warning 1612 Being purged log master-bin.000001 was not found
>>> *** must show one record, of the active binlog, left in the index file after
> PURGE ***
>>> show binary logs;
>>> Log_name File_size
>>> @@ -37,4 +41,79 @@ Level Code Message
>>> Error 1377 a problem with deleting master-bin.000001; consider examining
> correspondence of your binlog index file to the actual binlog files
>>> Error 1377 Fatal error during log purge
>>> reset master;
>>> +# crash_purge_before_update_index
>>> +flush logs;
>>> +SET SESSION debug="+d,crash_purge_before_update_index";
>>> +purge binary logs TO 'master-bin.000002';
>>> +ERROR HY000: Lost connection to MySQL server during query
>>> +./master-bin.000001
>>> +./master-bin.000002
>>> +./master-bin.000003
>>> +# crash_purge_non_critical_after_update_index
>>> +flush logs;
>>> +SET SESSION debug="+d,crash_purge_non_critical_after_update_index";
>>> +purge binary logs TO 'master-bin.000004';
>>> +ERROR HY000: Lost connection to MySQL server during query
>>> +./master-bin.000004
>>> +./master-bin.000005
>>> +# crash_purge_critical_after_update_index
>>> +flush logs;
>>> +SET SESSION debug="+d,crash_purge_critical_after_update_index";
>>> +purge binary logs TO 'master-bin.000006';
>>> +ERROR HY000: Lost connection to MySQL server during query
>>> +./master-bin.000006
>>> +./master-bin.000007
>>> +# crash_create_non_critical_before_update_index
>>> +SET SESSION debug="+d,crash_create_non_critical_before_update_index";
>>> +flush logs;
>>> +ERROR HY000: Lost connection to MySQL server during query
>>> +./master-bin.000006
>>> +./master-bin.000007
>>> +./master-bin.000008
>>> +# crash_create_critical_before_update_index
>>> +SET SESSION debug="+d,crash_create_critical_before_update_index";
>>> +flush logs;
>>> +ERROR HY000: Lost connection to MySQL server during query
>>> +./master-bin.000006
>>> +./master-bin.000007
>>> +./master-bin.000008
>>> +./master-bin.000009
>>> +# crash_create_after_update_index
>>> +SET SESSION debug="+d,crash_create_after_update_index";
>>> +flush logs;
>>> +ERROR HY000: Lost connection to MySQL server during query
>>> +./master-bin.000006
>>> +./master-bin.000007
>>> +./master-bin.000008
>>> +./master-bin.000009
>>> +./master-bin.000010
>>> +./master-bin.000011
>>> +#
>>> +# This should put the server in unsafe state and stop
>>> +# accepting any command. If we inject a fault at this
>>> +# point and continue the execution the server crashes.
>>> +# Besides the flush command does not report an error.
>>> +#
>>> +# fault_injection_registering_index
>>> +SET SESSION debug="+d,fault_injection_registering_index";
>>> +flush logs;
>>> +./master-bin.000006
>>> +./master-bin.000007
>>> +./master-bin.000008
>>> +./master-bin.000009
>>> +./master-bin.000010
>>> +./master-bin.000011
>>> +./master-bin.000012
>>> +# fault_injection_updating_index
>>> +SET SESSION debug="+d,fault_injection_updating_index";
>>> +flush logs;
>>> +./master-bin.000006
>>> +./master-bin.000007
>>> +./master-bin.000008
>>> +./master-bin.000009
>>> +./master-bin.000010
>>> +./master-bin.000011
>>> +./master-bin.000012
>>> +./master-bin.000013
>>> +SET SESSION debug="";
>>> End of tests
>>>
>>> === modified file 'mysql-test/suite/binlog/t/binlog_index.test'
>>> --- a/mysql-test/suite/binlog/t/binlog_index.test 2008-04-05 11:09:53 +0000
>>> +++ b/mysql-test/suite/binlog/t/binlog_index.test 2009-11-23 03:09:52 +0000
>>> @@ -3,6 +3,12 @@
>>> #
>>> source include/have_log_bin.inc;
>>> source include/not_embedded.inc;
>>> +call mtr.add_suppression('Attempting backtrace');
>>> +call mtr.add_suppression('MSYQL_LOG::purge_logs failed to process registered
> files that would be purged.');
>>> +call mtr.add_suppression('MSYQL_BIN_LOG::open failed to sync the index
> file');
>>> +call mtr.add_suppression('Turning logging off for the whole duration of the
> MySQL server process.');
>>> +call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to clean
> registers before purging logs.');
>>> +let $old=`select @@debug`;
>>>
>>> #
>>> # testing purge binary logs TO
>>> @@ -32,6 +38,7 @@ reset master;
>>> flush logs;
>>> flush logs;
>>> flush logs;
>>> +
>>> remove_file $MYSQLD_DATADIR/master-bin.000001;
>>>
>>> --echo *** must be a warning master-bin.000001 was not found ***
>>> @@ -47,7 +54,7 @@ source include/show_binary_logs.inc;
>>> #
>>> # testing a fatal error
>>> # Turning a binlog file into a directory must be a portable setup
>>> -#
>>> +#
>>>
>>> reset master;
>>>
>>> @@ -66,4 +73,127 @@ rmdir $MYSQLD_DATADIR/master-bin.000001;
>>> --disable_warnings
>>> reset master;
>>> --enable_warnings
>>> +
>>> +--echo # crash_purge_before_update_index
>>> +flush logs;
>>> +
>>> +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>>> +SET SESSION debug="+d,crash_purge_before_update_index";
>>> +--error 2013
>>> +purge binary logs TO 'master-bin.000002';
>>> +
>>> +--enable_reconnect
>>> +--source include/wait_until_connected_again.inc
>>> +
>>> +file_exists $MYSQLD_DATADIR/master-bin.000001;
>>> +file_exists $MYSQLD_DATADIR/master-bin.000002;
>>> +file_exists $MYSQLD_DATADIR/master-bin.000003;
>>> +cat_file $MYSQLD_DATADIR/master-bin.index;
>>> +
>>> +--echo # crash_purge_non_critical_after_update_index
>>> +flush logs;
>>> +
>>> +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>>> +SET SESSION debug="+d,crash_purge_non_critical_after_update_index";
>>> +--error 2013
>>> +purge binary logs TO 'master-bin.000004';
>>> +
>>> +--enable_reconnect
>>> +--source include/wait_until_connected_again.inc
>>> +
>>> +--error 1
>>> +file_exists $MYSQLD_DATADIR/master-bin.000001;
>>> +--error 1
>>> +file_exists $MYSQLD_DATADIR/master-bin.000002;
>>> +--error 1
>>> +file_exists $MYSQLD_DATADIR/master-bin.000003;
>>> +cat_file $MYSQLD_DATADIR/master-bin.index;
>>> +
>>> +--echo # crash_purge_critical_after_update_index
>>> +flush logs;
>>> +
>>> +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>>> +SET SESSION debug="+d,crash_purge_critical_after_update_index";
>>> +--error 2013
>>> +purge binary logs TO 'master-bin.000006';
>>> +
>>> +--enable_reconnect
>>> +--source include/wait_until_connected_again.inc
>>> +
>>> +--error 1
>>> +file_exists $MYSQLD_DATADIR/master-bin.000004;
>>> +--error 1
>>> +file_exists $MYSQLD_DATADIR/master-bin.000005;
>>> +file_exists $MYSQLD_DATADIR/master-bin.000006;
>>> +file_exists $MYSQLD_DATADIR/master-bin.000007;
>>> +--error 1
>>> +file_exists $MYSQLD_DATADIR/master-bin.000008;
>>> +cat_file $MYSQLD_DATADIR/master-bin.index;
>>> +
>>> +--echo # crash_create_non_critical_before_update_index
>>> +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>>> +SET SESSION debug="+d,crash_create_non_critical_before_update_index";
>>> +--error 2013
>>> +flush logs;
>>> +
>>> +--enable_reconnect
>>> +--source include/wait_until_connected_again.inc
>>> +
>>> +file_exists $MYSQLD_DATADIR/master-bin.000008;
>>> +--error 1
>>> +file_exists $MYSQLD_DATADIR/master-bin.000009;
>>> +cat_file $MYSQLD_DATADIR/master-bin.index;
>>> +
>>> +--echo # crash_create_critical_before_update_index
>>> +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>>> +SET SESSION debug="+d,crash_create_critical_before_update_index";
>>> +--error 2013
>>> +flush logs;
>>> +
>>> +--enable_reconnect
>>> +--source include/wait_until_connected_again.inc
>>> +
>>> +file_exists $MYSQLD_DATADIR/master-bin.000009;
>>> +--error 1
>>> +file_exists $MYSQLD_DATADIR/master-bin.000010;
>>> +--error 1
>>> +file_exists $MYSQLD_DATADIR/master-bin.000011;
>>> +cat_file $MYSQLD_DATADIR/master-bin.index;
>>> +
>>> +--echo # crash_create_after_update_index
>>> +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>>> +SET SESSION debug="+d,crash_create_after_update_index";
>>> +--error 2013
>>> +flush logs;
>>> +
>>> +--enable_reconnect
>>> +--source include/wait_until_connected_again.inc
>>> +
>>> +file_exists $MYSQLD_DATADIR/master-bin.000010;
>>> +file_exists $MYSQLD_DATADIR/master-bin.000011;
>>> +cat_file $MYSQLD_DATADIR/master-bin.index;
>>> +
>>> +--echo #
>>> +--echo # This should put the server in unsafe state and stop
>>> +--echo # accepting any command. If we inject a fault at this
>>> +--echo # point and continue the execution the server crashes.
>>> +--echo # Besides the flush command does not report an error.
>>> +--echo #
>>> +
>>> +--echo # fault_injection_registering_index
>>> +SET SESSION debug="+d,fault_injection_registering_index";
>>> +flush logs;
>>> +--source include/restart_mysqld.inc
>>> +
>>> +cat_file $MYSQLD_DATADIR/master-bin.index;
>>> +
>>> +--echo # fault_injection_updating_index
>>> +SET SESSION debug="+d,fault_injection_updating_index";
>>> +flush logs;
>>> +--source include/restart_mysqld.inc
>>> +
>>> +cat_file $MYSQLD_DATADIR/master-bin.index;
>>> +
>>> +eval SET SESSION debug="$old";
>>> +
>>> --echo End of tests
>>>
>>> === modified file 'sql/log.cc'
>>> --- a/sql/log.cc 2009-11-20 20:56:43 +0000
>>> +++ b/sql/log.cc 2009-11-23 03:09:52 +0000
>>> @@ -2429,7 +2429,7 @@ MYSQL_BIN_LOG::MYSQL_BIN_LOG()
>>> */
>>> index_file_name[0] = 0;
>>> bzero((char*) &index_file, sizeof(index_file));
>>> - bzero((char*) &purge_temp, sizeof(purge_temp));
>>> + bzero((char*) ®ister_file, sizeof(register_file));
>>> }
>> OK
>>
>>> /* this is called only once */
>>> @@ -2473,7 +2473,7 @@ void MYSQL_BIN_LOG::init_pthread_objects
>>>
>>>
>>> bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
>>> - const char *log_name)
>>> + const char *log_name, bool need_mutex)
>>> {
>>> File index_file_nr= -1;
>>> DBUG_ASSERT(!my_b_inited(&index_file));
>> OK
>>
>>> @@ -2498,7 +2498,8 @@ bool MYSQL_BIN_LOG::open_index_file(cons
>>> 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 | MY_WAIT_IF_FULL)))
>>> + 0, MYF(MY_WME | MY_WAIT_IF_FULL)) ||
>>> + DBUG_EVALUATE_IF("fault_injection_openning_index", 1, 0))
>>> {
>>> /*
>>> TODO: all operations creating/deleting the index file or a log,
> should
>> OK
>>
>>> @@ -2509,10 +2510,31 @@ bool MYSQL_BIN_LOG::open_index_file(cons
>>> my_close(index_file_nr,MYF(0));
>>> return TRUE;
>>> }
>>> +
>>> + #ifdef HAVE_REPLICATION
>>> + /*
>>> + Sync the index by purging any binary log file that is not registered.
>>> + In other words, either purge binary log files that were removed from
>>> + the index but not purged from the file system due to a crash or purge
>>> + any binary log file that was created but not register in the index
>>> + due to a crash.
>>> + */
>>> +
>>> + if (set_register_file_name(index_file_name_arg) ||
>>> + open_register(FALSE) ||
>>> + purge_index_entry(NULL, NULL, need_mutex) ||
>>> + close_register() ||
>>> + DBUG_EVALUATE_IF("fault_injection_recovering_index", 1, 0))
>>> + {
>>> + sql_print_error("MYSQL_BIN_LOG::open_index_file failed to sync the index
> "
>>> + "file.");
>>> + return TRUE;
>>> + }
>>> + #endif
>>> +
>>> return FALSE;
>>> }
>>>
>> RC2: Why protect this with HAVE_REPLICATION? I don't think this is
>> replication specific, but rather binary log specific, correct?
>
> See comment above.
>
>>> -
>> RC1: Don't do this ^.
>>> /**
>>> Open a (new) binlog file.
>>>
>>> @@ -2533,17 +2555,56 @@ bool MYSQL_BIN_LOG::open(const char *log
>>> enum cache_type io_cache_type_arg,
>>> bool no_auto_events_arg,
>>> ulong max_size_arg,
>>> - bool null_created_arg)
>>> + bool null_created_arg,
>>> + bool need_mutex)
>>> {
>>> File file= -1;
>>> + char new_file_name[FN_REFLEN];
>>> +
>>> DBUG_ENTER("MYSQL_BIN_LOG::open");
>>> DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg));
>>>
>>> - write_error=0;
>>> + /*
>>> + This duplicates some of the work done by the MYSQL_LOG constructor but
> we
>>> + need it in here in order to define the name of the file that will be
> created
>>> + and register it before the real operation.
>>> + */
>>> + MYSQL_LOG::init(log_type_arg, io_cache_type_arg);
>>> + if (new_name && !strmov(new_file_name, new_name))
>>> + {
>>> + sql_print_error("MSYQL_BIN_LOG::open failed to allocate memory for "
>>> + "file name.");
>>> + DBUG_RETURN(1);
>>> + }
>>> + else if (!new_name && generate_new_name(new_file_name, log_name))
>>> + {
>>> + sql_print_error("MSYQL_BIN_LOG::open failed to generate new file
> name.");
>>> + DBUG_RETURN(1);
>>> + }
>> RC3: Why not make this part of a private method?
>
>
> I will follow Jasonh's suggestion.
>
>>> + #ifdef HAVE_REPLICATION
>>> + if (open_register(TRUE) ||
>>> + register_create_index_entry(new_file_name) ||
>>> + sync_register() ||
>>> + DBUG_EVALUATE_IF("fault_injection_registering_index", 1, 0))
>>> + {
>>> + sql_print_error("MSYQL_BIN_LOG::open failed to sync the index file.");
>>> + DBUG_RETURN(1);
>>> + }
>>> + DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index",
> abort(););
>>> + #endif
>> RC2: Again, I don't think this piece of code should be guarded
>> with HAVE_REPLICATION.
>
>
> See comment above.
>
>>> + write_error= 0;
>>>
>>> /* open the main log file */
>>> - if (MYSQL_LOG::open(log_name, log_type_arg, new_name, io_cache_type_arg))
>>> + if (MYSQL_LOG::open(log_name, log_type_arg, new_file_name,
>>> + io_cache_type_arg))
>>> + {
>>> + #ifdef HAVE_REPLICATION
>>> + (void) close_register();
>>> + #endif
>> RC2: Same here.
>>
>>> DBUG_RETURN(1); /* all warnings issued */
>>> + }
>>>
>>> init(no_auto_events_arg, max_size_arg);
>>>
>>> @@ -2569,9 +2630,6 @@ bool MYSQL_BIN_LOG::open(const char *log
>>> write_file_name_to_index_file= 1;
>>> }
>>>
>>> - DBUG_ASSERT(my_b_inited(&index_file) != 0);
>>> - reinit_io_cache(&index_file, WRITE_CACHE,
>>> - my_b_filelength(&index_file), 0, 0);
>>> if (need_start_event && !no_auto_events)
>>> {
>>> /*
>> OK
>>
>>> @@ -2629,23 +2687,43 @@ bool MYSQL_BIN_LOG::open(const char *log
>>>
>>> if (write_file_name_to_index_file)
>>> {
>>> + #ifdef HAVE_REPLICATION
>>> + DBUG_EXECUTE_IF("crash_create_critical_before_update_index",
> abort(););
>>> + #endif
>>> +
>>> + DBUG_ASSERT(my_b_inited(&index_file) != 0);
>>> + reinit_io_cache(&index_file, WRITE_CACHE,
>>> + my_b_filelength(&index_file), 0, 0);
>>> /*
>>> As this is a new log file, we write the file name to the index
>>> file. As every time we write to the index file, we sync it.
>>> */
>>> - if (my_b_write(&index_file, (uchar*) log_file_name,
>>> - strlen(log_file_name)) ||
>>> - my_b_write(&index_file, (uchar*) "\n", 1) ||
>>> - flush_io_cache(&index_file) ||
>>> + if (DBUG_EVALUATE_IF("fault_injection_updating_index", 1, 0) ||
>>> + my_b_write(&index_file, (uchar*) log_file_name,
>>> + strlen(log_file_name)) ||
>>> + my_b_write(&index_file, (uchar*) "\n", 1) ||
>>> + flush_io_cache(&index_file) ||
>>> my_sync(index_file.file, MYF(MY_WME)))
>>> - goto err;
>>> + goto err;
>>> +
>>> + #ifdef HAVE_REPLICATION
>>> + DBUG_EXECUTE_IF("crash_create_after_update_index", abort(););
>>> + #endif
>> RC2: Same here.
>>
>>> }
>>> }
>>> log_state= LOG_OPENED;
>>>
>>> + #ifdef HAVE_REPLICATION
>>> + (void) close_register();
>>> + #endif
>>> +
>> RC2: Same here.
>>
>>> DBUG_RETURN(0);
>>>
>>> err:
>>> + #ifdef HAVE_REPLICATION
>>> + (void) purge_index_entry(NULL, NULL, need_mutex);
>>> + (void) close_register();
>>> + #endif
>> RC2: Same here.
>>
>>> 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, \
>>> @@ -2902,8 +2980,10 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
>>> name=0; // Protect against free
>>> close(LOG_CLOSE_TO_BE_OPENED);
>>>
>>> - /* First delete all old log files */
>>> -
>>> + /*
>>> + First delete all old log files.
>>> + Note that this routine is not completely safe.
>> S1: Please add a brief description why this is not safe.
>
> Ok. Done.
>
>>> + */
>>> if (find_log_pos(&linfo, NullS, 0))
>>> {
>>> error=1;
>>> @@ -2914,7 +2994,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
>>> {
>>> if ((error= my_delete_allow_opened(linfo.log_file_name, MYF(0))) != 0)
>>> {
>>> - if (my_errno == ENOENT)
>>> + if (my_errno == ENOENT)
>> RC1: Also here.
>>
>>> {
>>> push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
>>> ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
>>> @@ -2945,7 +3025,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
>>> close(LOG_CLOSE_INDEX);
>>> if ((error= my_delete_allow_opened(index_file_name, MYF(0)))) // Reset
> (open will update)
>>> {
>>> - if (my_errno == ENOENT)
>>> + if (my_errno == ENOENT)
>> RC1: Also here.
>>
>>> {
>>> push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
>>> ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
>>> @@ -2970,8 +3050,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
>>> }
>>> if (!thd->slave_thread)
>>> need_start_event=1;
>>> - if (!open_index_file(index_file_name, 0))
>>> - open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size,
> 0);
>>> + if (!open_index_file(index_file_name, 0, FALSE))
>>> + open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0,
> FALSE);
>>> my_free((uchar*) save_name, MYF(0));
>>>
>>> err:
>> OK
>>
>>> @@ -3038,7 +3118,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay
>>> Read the next log file name from the index file and pass it back to
>>> the caller.
>>> */
>>> - if((error=find_log_pos(&rli->linfo, rli->event_relay_log_name,
> 0)) ||
>>> + if((error=find_log_pos(&rli->linfo, rli->event_relay_log_name,
> 0)) ||
>>> (error=find_next_log(&rli->linfo, 0)))
>>> {
>>> char buff[22];
>> OK
>>
>>> @@ -3090,7 +3170,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay
>>> pthread_cond_broadcast(&rli->log_space_cond);
>>>
>>> /*
>>> - * Need to update the log pos because purge logs has been called
>>> + * Need to update the log pos because purge logs has been called
>>> * after fetching initially the log pos at the begining of the method.
>>> */
>>> if((error=find_log_pos(&rli->linfo, rli->event_relay_log_name,
> 0)))
>> RC1: Same here.
>>
>>> @@ -3152,13 +3232,13 @@ int MYSQL_BIN_LOG::update_log_index(LOG_
>>> my_stat() or my_delete()
>>> */
>>>
>>> -int MYSQL_BIN_LOG::purge_logs(const char *to_log,
>>> +int MYSQL_BIN_LOG::purge_logs(const char *to_log,
>>> bool included,
>>> - bool need_mutex,
>>> - bool need_update_threads,
>>> + bool need_mutex,
>>> + bool need_update_threads,
>> RC1: Same here.
>>
>>> ulonglong *decrease_log_space)
>>> {
>>> - int error;
>>> + int error= 0;
>> Good.
>>
>>> bool exit_loop= 0;
>>> LOG_INFO log_info;
>>> THD *thd= current_thd;
>>> @@ -3167,35 +3247,17 @@ int MYSQL_BIN_LOG::purge_logs(const char
>>>
>>> if (need_mutex)
>>> pthread_mutex_lock(&LOCK_index);
>>> - if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/)))
>>> + if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/)))
>>> {
>> RC1: Same here.
>>
>>> - sql_print_error("MYSQL_LOG::purge_logs was called with file %s not "
>>> + sql_print_error("MYSQL_BIN_LOG::purge_logs was called with file %s not
> "
>>> "listed in the index.", to_log);
>> Good.
>>
>>> goto err;
>>> }
>>>
>>> - /*
>>> - For crash recovery reasons the index needs to be updated before
>>> - any files are deleted. Move files to be deleted into a temp file
>>> - to be processed after the index is updated.
>>> - */
>>> - if (!my_b_inited(&purge_temp))
>>> + if ((error= open_register(TRUE)))
>>> {
>>> - if ((error=open_cached_file(&purge_temp, mysql_tmpdir, TEMP_PREFIX,
>>> - DISK_BUFFER_SIZE, MYF(MY_WME))))
>>> - {
>>> - sql_print_error("MYSQL_LOG::purge_logs failed to open purge_temp");
>>> - goto err;
>>> - }
>>> - }
>>> - else
>>> - {
>>> - if ((error=reinit_io_cache(&purge_temp, WRITE_CACHE, 0, 0, 1)))
>>> - {
>>> - sql_print_error("MYSQL_LOG::purge_logs failed to reinit purge_temp "
>>> - "for write");
>>> - goto err;
>>> - }
>>> + sql_print_error("MYSQL_BIN_LOG::purge_logs failed to sync the index
> file.");
>>> + goto err;
>>> }
>>>
>>> /*
>> OK
>>
>>> @@ -3205,20 +3267,27 @@ int MYSQL_BIN_LOG::purge_logs(const char
>>> if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
>>> goto err;
>>> while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included))
> &&
>>> + !is_active(log_info.log_file_name) &&
>>> !log_in_use(log_info.log_file_name))
>>> {
>>> - if ((error=my_b_write(&purge_temp, (const
> uchar*)log_info.log_file_name,
>>> - strlen(log_info.log_file_name))) ||
>>> - (error=my_b_write(&purge_temp, (const uchar*)"\n", 1)))
>>> + if ((error= register_purge_index_entry(log_info.log_file_name)))
>>> {
>>> - sql_print_error("MYSQL_LOG::purge_logs failed to copy %s to
> purge_temp",
>>> + sql_print_error("MYSQL_BIN_LOG::purge_logs failed to copy %s to
> register file.",
>>> log_info.log_file_name);
>>> goto err;
>>> }
>>>
>>> if (find_next_log(&log_info, 0) || exit_loop)
>>> break;
>>> - }
>>> + }
>>> +
>>> + DBUG_EXECUTE_IF("crash_purge_before_update_index", abort(););
>>> +
>>> + if ((error= sync_register()))
>>> + {
>>> + sql_print_error("MSYQL_LOG::purge_logs failed to flush register
> file.");
>>> + goto err;
>>> + }
>> RC4: Since you have changed the ones before, please fix this
>> as well: MYSQL_LOG --> MYSQL_LOG_BIN. Also, fix the ones
>> that show up after.
>
>
> Done.
>
>
>>>
>>> /* We know how many files to delete. Update index file. */
>>> if ((error=update_log_index(&log_info, need_update_threads)))
>>> @@ -3227,29 +3296,141 @@ int MYSQL_BIN_LOG::purge_logs(const char
>>> goto err;
>>> }
>>>
>>> - DBUG_EXECUTE_IF("crash_after_update_index", abort(););
>>> + DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", abort(););
>>> +
>>> +err:
>>> + /* Read each entry from register_file and delete the file. */
>>> + if ((error= purge_index_entry(thd, decrease_log_space, FALSE)))
>>> + sql_print_error("MSYQL_LOG::purge_logs failed to process registered
> files"
>>> + " that would be purged.");
>> RC4: Same here.
>>
>>> + (void) close_register();
>>> +
>>> + DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", abort(););
>>> +
>>> + if (need_mutex)
>>> + pthread_mutex_unlock(&LOCK_index);
>>> + DBUG_RETURN(error);
>>> +}
>>> +
>>> +int MYSQL_BIN_LOG::set_register_file_name(const char *base_file_name)
>>> +{
>>> + int error= 0;
>>> + DBUG_ENTER("MYSQL_BIN_LOG::set_register_file_name");
>>> + if (fn_format(register_file_name, base_file_name, mysql_data_home,
>>> + ".~rec~", MYF(MY_UNPACK_FILENAME | MY_SAFE_PATH |
>>> + MY_REPLACE_EXT)) == NULL)
>>> + {
>>> + error= 1;
>>> + sql_print_error("MYSQL_BIN_LOG::set_register_file_name failed to set
> "
>>> + "file name.");
>>> +
>>> + }
>>> + DBUG_RETURN(error);
>>> +}
>>> +
>>> +int MYSQL_BIN_LOG::open_register(bool destroy)
>>> +{
>>> + int error= 0;
>>> + File file= -1;
>>>
>>> - /* Switch purge_temp for read. */
>>> - if ((error=reinit_io_cache(&purge_temp, READ_CACHE, 0, 0, 0)))
>>> + DBUG_ENTER("MYSQL_BIN_LOG::register_file");
>>> +
>>> + if (destroy)
>>> + (void) close_register();
>>> +
>>> + if (!my_b_inited(®ister_file))
>>> {
>>> - sql_print_error("MSYQL_LOG::purge_logs failed to reinit purge_temp "
>>> + if ((file= my_open(register_file_name, O_RDWR | O_CREAT | O_BINARY,
>>> + MYF(MY_WME | ME_WAITTANG))) < 0 ||
>>> + init_io_cache(®ister_file, file, IO_SIZE,
>>> + (destroy ? WRITE_CACHE : READ_CACHE),
>>> + 0, 0, MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL)))
>>> + {
>>> + error= 1;
>>> + sql_print_error("MYSQL_BIN_LOG::open_register failed to open register
> "
>>> + " file.");
>>> + }
>>> + }
>>> + DBUG_RETURN(error);
>>> +}
>>> +
>>> +int MYSQL_BIN_LOG::close_register(void)
>>> +{
>>> + int error= 0;
>>> +
>>> + DBUG_ENTER("MYSQL_BIN_LOG::close_register");
>>> +
>>> + if (my_b_inited(®ister_file))
>>> + {
>>> + end_io_cache(®ister_file);
>>> + error= my_close(register_file.file, MYF(0));
>>> + }
>>> + my_delete(register_file_name, MYF(0));
>>> + bzero((char*) ®ister_file, sizeof(register_file));
>>> +
>>> + DBUG_RETURN(error);
>>> +}
>>> +
>>> +int MYSQL_BIN_LOG::sync_register(void)
>>> +{
>>> + int error= 0;
>>> + DBUG_ENTER("MYSQL_BIN_LOG::sync_register");
>>> +
>>> + if ((error= flush_io_cache(®ister_file)) ||
>>> + (error= my_sync(register_file.file, MYF(MY_WME))))
>>> + DBUG_RETURN(error);
>>> +
>>> + DBUG_RETURN(error);
>>> +}
>>> +
>>> +int MYSQL_BIN_LOG::register_purge_index_entry(const char *entry)
>>> +{
>>> + int error= 0;
>>> + DBUG_ENTER("MYSQL_BIN_LOG::register_purge_index_entry");
>>> +
>>> + if ((error=my_b_write(®ister_file, (const uchar*)entry,
> strlen(entry))) ||
>>> + (error=my_b_write(®ister_file, (const uchar*)"\n", 1)))
>>> + DBUG_RETURN (error);
>>> +
>>> + DBUG_RETURN(error);
>>> +}
>>> +
>>> +
>>> +int MYSQL_BIN_LOG::register_create_index_entry(const char *entry)
>>> +{
>>> + DBUG_ENTER("MYSQL_BIN_LOG::register_create_index_entry");
>>> + DBUG_RETURN(register_purge_index_entry(entry));
>>> +}
>>> +
>>> +int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong
> *decrease_log_space,
>>> + bool need_mutex)
>>> +{
>>> + MY_STAT s;
>>> + int error= 0;
>>> + LOG_INFO log_info;
>>> + LOG_INFO check_log_info;
>>> +
>>> + DBUG_ENTER("MYSQL_BIN_LOG:_purge_index_entry");
>>> +
>>> + if ((error=reinit_io_cache(®ister_file, READ_CACHE, 0, 0, 0)))
>>> + {
>>> + sql_print_error("MSYQL_BIN_LOG::purge_index_entry failed to reinit
> register file "
>>> "for read");
>>> goto err;
>>> }
>>>
>>> - /* Read each entry from purge_temp and delete the file. */
>>> for (;;)
>>> {
>>> uint length;
>>>
>>> - if ((length=my_b_gets(&purge_temp, log_info.log_file_name,
>>> + if ((length=my_b_gets(®ister_file, log_info.log_file_name,
>>> FN_REFLEN)) <= 1)
>>> {
>>> - if (purge_temp.error)
>>> + if (register_file.error)
>>> {
>>> - error= purge_temp.error;
>>> - sql_print_error("MSYQL_LOG::purge_logs error %d reading from "
>>> - "purge_temp", error);
>>> + error= register_file.error;
>>> + sql_print_error("MSYQL_BIN_LOG::purge_index_entry error %d reading
> from "
>>> + "register file.", error);
>>> goto err;
>>> }
>> OK.
>>
>>> @@ -3260,12 +3441,9 @@ int MYSQL_BIN_LOG::purge_logs(const char
>>> /* Get rid of the trailing '\n' */
>>> log_info.log_file_name[length-1]= 0;
>>>
>>> - ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
>>> -
>>> - MY_STAT s;
>>> if (!my_stat(log_info.log_file_name, &s, MYF(0)))
>>> {
>>> - if (my_errno == ENOENT)
>>> + if (my_errno == ENOENT)
>> RC1: Same here.
>>
>>> {
>>> /*
>>> It's not fatal if we can't stat a log file that does not exist;
>>> @@ -3310,64 +3488,71 @@ int MYSQL_BIN_LOG::purge_logs(const char
>>> }
>>> else
>>> {
>>> - DBUG_PRINT("info",("purging %s",log_info.log_file_name));
>>> - if (!my_delete(log_info.log_file_name, MYF(0)))
>>> - {
>>> - if (decrease_log_space)
>>> - *decrease_log_space-= s.st_size;
>>> - }
>>> - else
>>> + if (find_log_pos(&check_log_info, log_info.log_file_name,
> need_mutex))
>>> {
>> RC5: Should you check that return value of find_log_pos is
>> LOG_INFO_EOF ?
>
>
> This cannot happen because you are reading from the temporary file.
> So the files were checked before calling the find_log_pos.
>
>>> - if (my_errno == ENOENT)
>>> + if (!need_mutex)
>>> {
>>> - if (thd)
>>> - {
>>> - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
>>> - ER_LOG_PURGE_NO_FILE,
> ER(ER_LOG_PURGE_NO_FILE),
>>> - log_info.log_file_name);
>>> - }
>>> - sql_print_information("Failed to delete file '%s'",
>>> - log_info.log_file_name);
>>> - my_errno= 0;
>>> + /*
>>> + This is to avoid triggering an error in NDB.
>>> + */
>>> + ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
>>> + }
>>> +
>>> + DBUG_PRINT("info",("purging %s",log_info.log_file_name));
>>> + if (!my_delete(log_info.log_file_name, MYF(0)))
>>> + {
>>> + if (decrease_log_space)
>>> + *decrease_log_space-= s.st_size;
>>> }
>>> else
>>> {
>>> - if (thd)
>>> + if (my_errno == ENOENT)
>>> {
>>> - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
>>> - ER_BINLOG_PURGE_FATAL_ERR,
>>> - "a problem with deleting %s; "
>>> - "consider examining correspondence "
>>> - "of your binlog index file "
>>> - "to the actual binlog files",
>>> + if (thd)
>>> + {
>>> + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
>>> + ER_LOG_PURGE_NO_FILE,
> ER(ER_LOG_PURGE_NO_FILE),
>>> + log_info.log_file_name);
>>> + }
>>> + sql_print_information("Failed to delete file '%s'",
>>> log_info.log_file_name);
>>> + my_errno= 0;
>>> }
>>> else
>>> {
>>> - sql_print_information("Failed to delete file '%s'; "
>>> + if (thd)
>>> + {
>>> + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
>>> + ER_BINLOG_PURGE_FATAL_ERR,
>>> + "a problem with deleting %s; "
>>> "consider examining correspondence "
>>> "of your binlog index file "
>>> "to the actual binlog files",
>>> log_info.log_file_name);
>>> - }
>>> - if (my_errno == EMFILE)
>>> - {
>>> - DBUG_PRINT("info",
>>> - ("my_errno: %d, set ret = LOG_INFO_EMFILE",
> my_errno));
>>> - error= LOG_INFO_EMFILE;
>>> + }
>>> + else
>>> + {
>>> + sql_print_information("Failed to delete file '%s'; "
>>> + "consider examining correspondence "
>>> + "of your binlog index file "
>>> + "to the actual binlog files",
>>> + log_info.log_file_name);
>>> + }
>>> + if (my_errno == EMFILE)
>>> + {
>>> + DBUG_PRINT("info",
>>> + ("my_errno: %d, set ret = LOG_INFO_EMFILE",
> my_errno));
>>> + error= LOG_INFO_EMFILE;
>>> + goto err;
>>> + }
>>> + error= LOG_INFO_FATAL;
>>> goto err;
>>> }
>>> - error= LOG_INFO_FATAL;
>>> - goto err;
>>> }
>>> }
>>> }
>>> }
>>> -
>>> err:
>>> - close_cached_file(&purge_temp);
>>> - if (need_mutex)
>>> - pthread_mutex_unlock(&LOCK_index);
>>> DBUG_RETURN(error);
>>> }
>>
>> OK.
>>
>>> @@ -3407,7 +3592,8 @@ int MYSQL_BIN_LOG::purge_logs_before_dat
>>> goto err;
>>>
>>> while (strcmp(log_file_name, log_info.log_file_name) &&
>>> - !log_in_use(log_info.log_file_name))
>>> + !is_active(log_info.log_file_name) &&
>>> + !log_in_use(log_info.log_file_name))
>>> {
>>> if (!my_stat(log_info.log_file_name, &stat_area, MYF(0)))
>>> {
>> OK
>>
>>> @@ -3416,14 +3602,6 @@ int MYSQL_BIN_LOG::purge_logs_before_dat
>>> /*
>>> It's not fatal if we can't stat a log file that does not exist.
>>> */
>>> - if (thd)
>>> - {
>>> - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
>>> - ER_LOG_PURGE_NO_FILE,
> ER(ER_LOG_PURGE_NO_FILE),
>>> - log_info.log_file_name);
>>> - }
>>> - sql_print_information("Failed to execute my_stat on file '%s'",
>>> - log_info.log_file_name);
>>> my_errno= 0;
>>> }
>>> else
>>> @@ -3604,6 +3782,7 @@ void MYSQL_BIN_LOG::new_file_impl(bool n
>>> name=0; // Don't free name
>>> close(LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX);
>>>
>>> +
>> RC1: Same here.
>>
>>> /*
>>> Note that at this point, log_state != LOG_CLOSED (important for
> is_open()).
>>> */
>>> @@ -3618,9 +3797,9 @@ void MYSQL_BIN_LOG::new_file_impl(bool n
>>> */
>>>
>>> /* reopen index binlog file, BUG#34582 */
>>> - if (!open_index_file(index_file_name, 0))
>>> - open(old_name, log_type, new_name_ptr,
>>> - io_cache_type, no_auto_events, max_size, 1);
>>> + if (!open_index_file(index_file_name, 0, FALSE))
>>> + open(old_name, log_type, new_name_ptr,
>>> + io_cache_type, no_auto_events, max_size, 1, FALSE);
>>> my_free(old_name,MYF(0));
>>>
>>> end:
>>> @@ -5522,7 +5701,7 @@ int TC_LOG_BINLOG::open(const char *opt_
>>> if (using_heuristic_recover())
>>> {
>>> /* generate a new binlog to mask a corrupted one */
>>> - open(opt_name, LOG_BIN, 0, WRITE_CACHE, 0, max_binlog_size, 0);
>>> + open(opt_name, LOG_BIN, 0, WRITE_CACHE, 0, max_binlog_size, 0, TRUE);
>>> cleanup();
>>> return 1;
>>> }
>> OK
>>
>>> === modified file 'sql/log.h'
>>> --- a/sql/log.h 2009-06-18 13:52:46 +0000
>>> +++ b/sql/log.h 2009-11-23 03:09:52 +0000
>>> @@ -233,14 +233,15 @@ class MYSQL_BIN_LOG: public TC_LOG, priv
>>> pthread_cond_t update_cond;
>>> ulonglong bytes_written;
>>> IO_CACHE index_file;
>>> + char index_file_name[FN_REFLEN];
>>> /*
>>> - purge_temp is a temp file used in purge_logs so that the index file
>>> + purge_file is a temp file used in purge_logs so that the index file
>>> can be updated before deleting files from disk, yielding better crash
>>> recovery. It is created on demand the first time purge_logs is called
>>> and then reused for subsequent calls. It is cleaned up in cleanup().
>>> */
>>> - IO_CACHE purge_temp;
>>> - char index_file_name[FN_REFLEN];
>>> + IO_CACHE register_file;
>>> + char register_file_name[FN_REFLEN];
>>> /*
>>> The max size before rotation (usable only if log_type == LOG_BIN:
> binary
>>> logs and relay logs).
>> OK
>>
>>> @@ -349,9 +350,10 @@ public:
>>> const char *new_name,
>>> enum cache_type io_cache_type_arg,
>>> bool no_auto_events_arg, ulong max_size,
>>> - bool null_created);
>>> + bool null_created,
>>> + bool need_mutex);
>>> bool open_index_file(const char *index_file_name_arg,
>>> - const char *log_name);
>>> + const char *log_name, bool need_mutex);
>>> /* Use this to start writing a new log file */
>>> void new_file();
>> OK
>>
>>> @@ -384,6 +386,15 @@ public:
>>> ulonglong *decrease_log_space);
>>> int purge_logs_before_date(time_t purge_time);
>>> int purge_first_log(Relay_log_info* rli, bool included);
>>> + int set_register_file_name(const char *base_file_name);
>>> + int open_register(bool destroy);
>>> + int close_register(void);
>>> + int clean_register(void);
>>> + int sync_register(void);
>>> + int register_purge_index_entry(const char* entry);
>>> + int register_create_index_entry(const char* entry);
>>> + int purge_index_entry(THD *thd, ulonglong *decrease_log_space,
>>> + bool need_mutex);
>>> bool reset_logs(THD* thd);
>>> void close(uint exiting);
>>>
>> OK. Perhaps I would name the methods record instead of register.
>
>
> I've followed Jasonh's suggestion.
>
>>> === modified file 'sql/mysqld.cc'
>>> --- a/sql/mysqld.cc 2009-11-20 12:09:50 +0000
>>> +++ b/sql/mysqld.cc 2009-11-23 03:09:52 +0000
>>> @@ -3932,7 +3932,7 @@ a file name for --log-bin-index option",
>>> my_free(opt_bin_logname, MYF(MY_ALLOW_ZERO_PTR));
>>> opt_bin_logname=my_strdup(buf, MYF(0));
>>> }
>>> - if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln))
>>> + if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln, TRUE))
>>> {
>>> unireg_abort(1);
>>> }
>> OK
>>
>>> @@ -4096,7 +4096,7 @@ a file name for --log-bin-index option",
>>> }
>>>
>>> if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN,
> 0,
>>> - WRITE_CACHE, 0, max_binlog_size,
> 0))
>>> + WRITE_CACHE, 0, max_binlog_size, 0,
> TRUE))
>>> unireg_abort(1);
>>>
>>> #ifdef HAVE_REPLICATION
>> OK
>>
>>> === modified file 'sql/rpl_rli.cc'
>>> --- a/sql/rpl_rli.cc 2009-11-05 06:07:31 +0000
>>> +++ b/sql/rpl_rli.cc 2009-11-23 03:09:52 +0000
>>> @@ -181,10 +181,10 @@ a file name for --relay-log-index option
>>> 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) ||
>>> + if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln, TRUE)
> ||
>>> rli->relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, 0,
>>> (max_relay_log_size ? max_relay_log_size :
>>> - max_binlog_size), 1))
>>> + max_binlog_size), 1, TRUE))
>>> {
>>> pthread_mutex_unlock(&rli->data_lock);
>>> sql_print_error("Failed in open_log() called from
> init_relay_log_info()");
>>>
>> OK
>>
>>
>