Bug #93442 log.write_ahead_end_offset inits to error value
Submitted: 2 Dec 2018 2:45 Modified: 13 Dec 2018 0:17
Reporter: yuhui wang Email Updates:
Status: Closed Impact on me:
Category:MySQL Server: InnoDB storage engine Severity:S3 (Non-critical)
Version:8.0.13 OS:CentOS (Linux r10k04625.sqa.zmf 2.6.32)
Assigned to: CPU Architecture:x86
Tags: innodb redolog; WAL; write_ahead_end_offset; write_ahead;

[2 Dec 2018 2:45] yuhui wang
When i am scanning the codes about log module, i am wondering about the initialization of variable 'log.write_ahead_end_offset' in function 'log_start'.

'log.write_ahead_end_offset' is the end offset in the log files which write ahead has been done or is not required. In other words, write ahead mechanism will be invalid if 'log.write_ahead_end_offset' is too big. 

In function 'log_start', 'log.write_ahead_end_offset' is inited to 'log.current_file_end_offset' in which case i think is wrong. It will result write ahead mechanism out of work until rotate to next log file in function 'start_next_file'.

How to repeat:
Restart mysql server, use gdb to print 'log.write_ahead_end_offset' like this:
gdb -x gdbfile -batch -p 62622 | grep =
where gdbfile:
p log_sys->write_ahead_end_offset
p log_sys->current_file_lsn
p log_sys->current_file_real_offset
p log_sys->current_file_end_offset
p log_sys->write_lsn


You will find log_sys->write_ahead_end_offset do not change(approximate to log_sys->current_file_end_offset) until rotate to next log file.

Suggested fix:
$ git diff storage/innobase/log/log0log.cc
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 7fdb70e..4c159af 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -600,7 +600,7 @@ void log_start(log_t &log, checkpoint_no_t checkpoint_no, lsn_t checkpoint_lsn,
   log_files_update_offsets(log, start_lsn);
   log.write_ahead_end_offset =
-      ut_uint64_align_up(log.current_file_end_offset, srv_log_write_ahead_size);
+      ut_uint64_align_up(log.current_file_real_offset, srv_log_write_ahead_size);
   lsn_t block_lsn;
   byte *block;

Fix is easy, just use log.current_file_real_offset instead of log.current_file_end_offset.
[6 Dec 2018 21:07] Pawel Olchawa
I confirm - such performance bug exists.

As you pointed, the write-ahead optimization is disabled since MySQL is started until we switched to a next log file. Since then it's enabled.

Also, the fix you suggested seems proper.

Thank you for your contribution.
[13 Dec 2018 0:17] Daniel Price
Posted by developer:
Fixed as of the upcoming 8.0.15 release, and here's the changelog entry:

Write-ahead did not work as expected due to an incorrectly initialized

Thanks to Yuhui Wang for the contribution.