Bug #94758 record with REC_INFO_MIN_REC_FLAG is not the min record on non-leaf page
Submitted: 23 Mar 2019 5:15 Modified: 8 Apr 2019 12:57
Reporter: zhai weixiang (OCA) Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S3 (Non-critical)
Version:8.0 OS:Any
Assigned to: CPU Architecture:Any

[23 Mar 2019 5:15] zhai weixiang
Description:
While exposing records on root page, I found that the first user record maybe not the min record on that page. If we insert records into table with descending order. 

I'm not sure if it's expected because i'm not very familiar with this area. 

How to repeat:
Create table and insert record:

CREATE TABLE `t1` (  
 `a` int(11) NOT NULL,  
 `b` char(32) DEFAULT NULL,  
 PRIMARY KEY (`a`)  
);

delimiter |;  
create procedure test.p_init (n int, size int)  
begin  
 while n > 0 do  
  select round(RAND() * size) into @act_size;  
  set @data = repeat('a', @act_size);  
  insert into t1 values(n, @data );  
  set n= n-1;  
 end while;  
end|

delimiter ;|

call test.p_init(4000, 32);

Then add the following function to any place where it can be invoked by select * from t1 (for example, in ha_innobase::index_read)

void dict_index_print_root(dict_index_t* index) {
  mtr_t mtr;

  mtr_start(&mtr);

  mtr_s_lock(dict_index_get_lock(index), &mtr);

  const fil_space_t *space = fil_space_get(index->space);
  const page_size_t page_size(space->flags);
  page_id_t page_id(dict_index_get_space(index),
      dict_index_get_page(index));

  buf_block_t* block = btr_block_get(page_id, page_size, RW_S_LATCH, index,
      &mtr);

  if (!block) {
    mtr_commit(&mtr);
    return;
  }

  btr_pcur_t pcur;
  btr_pcur_init(&pcur);
  page_cur_t* page_cursor = btr_pcur_get_page_cur(&pcur);

  page_cur_set_before_first(block, page_cursor);
  page_cur_move_to_next(page_cursor);

  while (!page_rec_is_supremum(page_cur_get_rec(page_cursor))) {
    const rec_t* rec = page_cur_get_rec(page_cursor);
    rec_print(stderr, rec, index);
    page_cur_move_to_next(page_cursor);
  }

  mtr_commit(&mtr);
}

Printed result:
the pk of  first record is 80000e8f which has flag REC_INFO_MIN_REC_FLAG but is larger than next record 

PHYSICAL RECORD: n_fields 2; compact format; info bits 16
 0: len 4; hex 80000e8f; asc     ;;
 1: len 4; hex 00000014; asc     ;;
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 8000001c; asc     ;;
 1: len 4; hex 00000013; asc     ;;
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 8000012e; asc    .;;
 1: len 4; hex 00000012; asc     ;;
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000240; asc    @;;
 1: len 4; hex 00000011; asc     ;;
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000352; asc    R;;
 1: len 4; hex 00000010; asc     ;;
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000464; asc    d;;
 1: len 4; hex 0000000f; asc     ;;
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000576; asc    v;;
 1: len 4; hex 0000000e; asc     ;;
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000688; asc     ;;
 1: len 4; hex 0000000d; asc     ;;
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 8000079a; asc     ;;
 1: len 4; hex 0000000c; asc     ;;
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 800008ac; asc     ;;
 1: len 4; hex 0000000b; asc     ;;
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 800009be; asc     ;;
 1: len 4; hex 0000000a; asc     ;;
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000ad0; asc     ;;
 1: len 4; hex 00000009; asc     ;;
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000be2; asc     ;;
 1: len 4; hex 00000008; asc     ;;
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000cf4; asc     ;;
 1: len 4; hex 00000007; asc     ;;
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000e06; asc     ;;
 1: len 4; hex 00000005; asc     ;;
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000f18; asc     ;;
 1: len 4; hex 00000006; asc     ;;

Suggested fix:
I don't know
[26 Mar 2019 15:16] MySQL Verification Team
HI,

Thank you for your bug report.

I do not think that we can accept your bug report as such. We accept bug reports only on our own codebase. Changing our server code will change this behaviour.

Hence, please, send us a bug report that is based entirely on our unchanged binary.
[8 Apr 2019 2:05] zhai weixiang
Hi, Sinisa
Thank you for your reply

I'm not sure if it's by design. because only the people who want to make use of non-leaf node will be affected(who also  want to change the source code ). It's ok if setting to  Not a Bug because the value of the rec with REC_INFO_MIN_REC_FLAG is actually ignored (but the flag may need a better comment). I opened this bug here so any developer who find the weird behavior can reach here by searching from google :)
[8 Apr 2019 12:57] MySQL Verification Team
Thank you Zhai.

In the future, if you have any conclusions based on code analysis, and if you think it is a bug or a desirable code improvement, just post it here.