Bug #83313 write to log file before crash recovery if need to fixup undo-trunc
Submitted: 9 Oct 2016 9:08 Modified: 20 Jan 2017 4:39
Reporter: zhai weixiang (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S3 (Non-critical)
Version:5.7 OS:Any
Assigned to: CPU Architecture:Any
Tags: Contribution

[9 Oct 2016 9:08] zhai weixiang
Description:
If undo table space need to fixup during startup, it will be recreated before crash recovery process. I observed the log file was modified while testing it. 

How to repeat:
1. Enable online undo truncate. 
2. make a breakpoint, after the undo-trunc file is created, but before the file is removed.(in function trx_purge_initiate_truncate)
3.heavy workload to trigger online undo truncate. If the breakpoint is triggered, kill the server
3. restart the server with gdb, set first breakpoint at log_write_up_to, You will get the following backtrace:

log_write_up_to (lsn=8204, flush_to_disk=true)
buf_flush_page
buf_flush_or_remove_page
buf_flush_or_remove_pages
buf_flush_dirty_pages
buf_LRU_remove_pages
buf_LRU_flush_or_remove_pages
srv_undo_tablespaces_init

Then break fil_io, the backtrace will be:

fil_io
log_group_file_header_flush // fil_io
log_group_write_buf
log_write_up_to
...
..
srv_undo_tablespaces_init

So obviously something is written to logfile 

Suggested fix:
The root cause is that log_sys->buf_next_to_write isn't equal to log_sys->buf_free after invoking log_init. so it will write some meaningless data if log_write_up_to is called before crashing recovery. 
 
A simple fix based on 5.7.15

diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 1e807f8..b6ab0b3 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -854,7 +854,9 @@ log_init(void)
        log_block_init(log_sys->buf, log_sys->lsn);
        log_block_set_first_rec_group(log_sys->buf, LOG_BLOCK_HDR_SIZE);
 
-       log_sys->buf_free = LOG_BLOCK_HDR_SIZE;
+       log_sys->buf_free
+               = log_sys->buf_next_to_write
+               = LOG_BLOCK_HDR_SIZE;
        log_sys->lsn = LOG_START_LSN + LOG_BLOCK_HDR_SIZE;
 
        MONITOR_SET(MONITOR_LSN_CHECKPOINT_AGE,
[9 Oct 2016 9:31] zhai weixiang
edit category
[9 Oct 2016 11:46] zhai weixiang
ignore the suggested fix, it's buggy :(
[14 Oct 2016 12:10] zhai weixiang
add some debug inforation to help verifying the bug, based on 5.7.16 

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

Contribution: debug.diff (application/octet-stream, text), 3.51 KiB.

[14 Oct 2016 12:12] zhai weixiang
Apply the patch, comment out the changes made in function srv_undo_tablespaces_init, and then run test case suite/innodb_undo/t/truncate_recover.test
[7 Dec 2016 0:45] zhai weixiang
Anyone help verifying this bug ?
[20 Jan 2017 4:39] MySQL Verification Team
Hello Zhai,

Thank you for the report and contribution.

Thanks,
Umesh