Bug #94493 Question about the MLOG_REC_INSERT redo log preallocated
Submitted: 27 Feb 2019 12:21 Modified: 28 Feb 2019 2:15
Reporter: haiqing sun Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S3 (Non-critical)
Version:8.0.15 OS:CentOS
Assigned to: CPU Architecture:Any

[27 Feb 2019 12:21] haiqing sun
Description:
Hi:

I read the code about the MLOG_REC_INSERT record format, and I am confused about pre-allocated memory for the record:

       {
           log_ptr = mlog_open(mtr, 11 + 2 + 5 + 1 + 5 + 5 + MLOG_BUF_MARGIN);
           ....
           log_ptr = mlog_write_initial_log_record_fast(insert_rec, MLOG_REC_INSERT,
                                                   log_ptr, mtr);
        }
 

         log_end = &log_ptr[2 + 5 + 1 + 5 + 5 + MLOG_BUF_MARGIN];
        /* Write the cursor rec offset as a 2-byte ulint */
        mach_write_to_2(log_ptr, page_offset(cursor_rec));
        log_ptr += 2;

In the code, we allocate 11 bytes for the for the mtr during initialization, but in fact, the total use of bytes is 1(type) + 4(space_id) + 4(page_offset).

How to repeat:
version: 8.0.15
line: storage/innobase/page/page0cur.cc:953

Suggested fix:
I think maybe we only pre-allocate 9 bytes for the mtr during initialization. 

         log_ptr = mlog_open(mtr, 9 + 2 + 5 + 1 + 5 + 5 + MLOG_BUF_MARGIN);
[27 Feb 2019 15:41] MySQL Verification Team
Hi,

This is actually not a bug.

You have missed the following two statements:

  mach_write_to_2(log_ptr, page_offset(cursor_rec));
  log_ptr += 2;
[27 Feb 2019 16:05] haiqing sun
Yes, but if I am not mistaken that the following two statements are after the mtr initialization finished, and It does not include in 11 bytes.
[27 Feb 2019 16:09] haiqing sun
mach_write_to_2(log_ptr, page_offset(cursor_rec));
  log_ptr += 2;

the cursor record offset costs 2 bytes in the record, and the two bytes is after 11 bytes.
[27 Feb 2019 17:41] MySQL Verification Team
Hi,

Took me some time, but here it is ........ This is a code that requires 11 bytes .....

mach_write_to_1(log_ptr, type);
log_ptr++;

 log_ptr += mach_write_compressed(log_ptr, space_id);
 log_ptr += mach_write_compressed(log_ptr, page_no);

This is the initial records. 1 + 5 + 5 bytes = 11 bytes

mach_write_compressed() can write up to 5 bytes.

Over and done.

Not a bug !!!!!!!
[28 Feb 2019 2:15] haiqing sun
Yes, I see, thank you very much!
[28 Feb 2019 13:54] MySQL Verification Team
You are welcome.