Bug #73109 unnecessary redo log writing occasionally in function log_write_up_to
Submitted: 25 Jun 2014 8:38 Modified: 16 Sep 2014 23:44
Reporter: zhai weixiang (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S3 (Non-critical)
Version:5.7.4 OS:Any
Assigned to: CPU Architecture:Any

[25 Jun 2014 8:38] zhai weixiang
Description:

In function log_write_up_to, If flush_to_disk = false ,and  there is nothing to write,  it will exit the function quickly.

quoted code:

        if (!flush_to_disk
            && log_sys->buf_free == log_sys->buf_next_to_write) {
                /* Nothing to write and no flush to disk requested */

                mutex_exit(&(log_sys->mutex));

                return;
        }

But if flush_to_disk  = true, then a redo log writing was processed, no matter if log_sys->buf_free is equal to  log_sys->buf_next_to_write

I think the redo log written can be skipped and goto redo sync directly in this situation.

How to repeat:
read the code

Suggested fix:
A simple patch based on MySQL5.7.4

Index: storage/innobase/log/log0log.cc
===================================================================
--- storage/innobase/log/log0log.cc     (revision 5767)
+++ storage/innobase/log/log0log.cc     (working copy)
@@ -1235,6 +1235,9 @@
                log_sys->current_flush_lsn = log_sys->lsn;
                MONITOR_INC(MONITOR_PENDING_LOG_FLUSH);
                os_event_reset(log_sys->flush_event);
+
+               if (log_sys->buf_free == log_sys->buf_next_to_write)
+                       goto flush_op;
        }

        group = UT_LIST_GET_FIRST(log_sys->log_groups);
@@ -1242,6 +1245,8 @@
        start_offset = log_sys->buf_next_to_write;
        end_offset = log_sys->buf_free;

+       ut_a(start_offset != end_offset);
+
        area_start = ut_calc_align_down(start_offset, OS_FILE_LOG_BLOCK_SIZE);
        area_end = ut_calc_align(end_offset, OS_FILE_LOG_BLOCK_SIZE);

@@ -1300,6 +1305,7 @@

        log_sys_write_completion();

+flush_op:
        if (srv_unix_file_flush_method == SRV_UNIX_O_DSYNC) {
                /* O_DSYNC means the OS did not buffer the log file at all:
                so we have also flushed to disk what we have written */
[25 Jun 2014 9:16] zhai weixiang
Sorry , I posted a wrong fix .  Ignore the suggested fix,  I'll attach a new one.
[25 Jun 2014 9:45] zhai weixiang
a simple fix

Attachment: bug73109.diff (application/octet-stream, text), 1.29 KiB.

[26 Jun 2014 8:55] MySQL Verification Team
Thanks for reporting the issue, and supplying a patch along with it.
Verifying based on inspecting code.

Also, could you please sign the OCA, so that we can consider taking your patch? Please see the following for more details:

http://www.oracle.com/technetwork/community/oca-486395.html

Do you have a test case that can be used to trigger this condition as well? That would also be appreciated.

Thanks,
Umesh
[7 Jul 2014 6:59] zhai weixiang
Hi,  Umesh

I have send an email with signed document.  Do I need to reattach the patch  ?
[7 Jul 2014 7:05] MySQL Verification Team
Hello Zhai,

Imho not required to resend the patch if already attached to the bug report..
Shall check and let you know if required to do so and update you.

Regards,
Umesh
[18 Jul 2014 14:19] zhai weixiang
re-attach the patch

(*) I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.

Contribution: bug73109.diff (application/octet-stream, text), 1.29 KiB.

[21 Jul 2014 4:31] zhai weixiang
remove incorrect assert

(*) I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.

Contribution: bug73109.diff (application/octet-stream, text), 1.40 KiB.

[16 Sep 2014 23:44] Daniel Price
Fixed as of the upcoming 5.7.6 release, and here's the changelog entry:

If the log sequence number (LSN) has not increased, the
"log_write_up_to()" function should not initiate redo log writing.

Thank you for the bug report.