Bug #118768 Link_buf may not advance the tail correctly
Submitted: 1 Aug 10:29 Modified: 4 Aug 5:29
Reporter: Zihao Wang (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Storage Engines Severity:S3 (Non-critical)
Version:8.0 OS:Any
Assigned to: CPU Architecture:Any
Tags: Link_buf

[1 Aug 10:29] Zihao Wang
Description:
Recently, when I was reading the source code, I found that there was a logic bug in the func `add_link_advance_tail()` in ut0link_buf.h.

`add_link_advance_tail()` should add a directed link and advance the tail in the buffer if possible. Assume the link to be added is (start_pos, end_pos), if the `tail` of the Link_buf at this time is equal to `start_pos`, then `add_link_advance_tail()` will update the `tail` to `end_pos` directly, and quit.

This could be a bug. If the links are added to Link_buf in the sequence below:

* step1: add_link_advance_tail(0, 1)
* step2: add_link_advance_tail(2, 3)
* step3: add_link_advance_tail(1, 2)

After step 3, the `tail` of this Link_buf will be 2 due to the aforementioned bug. However, the expected value should be 3. If `validate_no_links()` is called after step 3, mysqld will exit due to assertion failure.

Since log_checkpointer and buf_flush_page_coordinator will call `advance_tail()` before performing a checkpoint and flushing dirty pages, this bug has no negative impact for now. But I recommend fixing it to prevent bugs in the future.

How to repeat:
Just read my description, and look at the corresponding code.

The code is at https://github.com/mysql/mysql-server/blob/b79ac1111737174c1b36ab5f63275f0191c000dc/storag...

'''
  if (position == from) {
    /* can advance m_tail directly and exclusively, and it is unlock */
    m_tail.store(to, std::memory_order_release);
  } else {
    auto index = slot_index(from);
    auto &slot = m_links[index];

    /* add link */
    slot.store(to, std::memory_order_release);

    auto stop_condition = [&](Position prev_pos, Position) {
      return (prev_pos > from);
    };

    advance_tail_until(stop_condition);
  }
'''
(when `position == from`, update `m_tail` and return directly)
[4 Aug 5:29] MySQL Verification Team
Hello Zihao Wang,

Thank you for the report and feedback.
Verifying for now so that development can take a look on this.

regards,
Umesh