微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

insert进行第一次乐观插入逻辑分析

本篇内容主要讲解“insert进行第一次乐观插入逻辑分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“insert进行第一次乐观插入逻辑分析”吧!

  • 可能会触发锁继承

  • 唯一检查会可能触发LOCK_S也是这里进入的

  • 插入之前要定位数据

  • undo在redo生成之前生成

逻辑入口如下:

->row_ins_sec_index_entry_low 第一次进行乐观插入 mode=BTR_MODIFY_LEAF
  -> 是否是唯一键 是 row_ins_scan_sec_index_for_duplicate 进行唯一性检查
  -> 进行唯一性检测结果处理
  -> 进行数据查找 btr_cur_search_to_nth_level
     ->page_cur_search_with_match_bytes
  -> 如果只是检查重复值跳过下面逻辑 if (dup_chk_only) 
  -> 进行乐观插入,假设不修改B+树结构 btr_cur_optimistic_insert,主要通过BTR_MODIFY_LEAF标示识别,此处不考虑压缩页
    ->计算转换逻辑记录(元组)为物理记录后的长度 rec_get_converted_size
      ->rec_get_converted_size_comp
    ->是否需要外部存储page_zip_rec_needs_ext
    ->获取块的空闲空间大小 page_get_max_insert_size_after_reorganize 备注(1
    ->进行是否需要悲观插入的逻辑判断,主要还是空间不够的情况 备注(2,如果需要悲观插入则这里返回了
    ->如果是主键还需要预留部分空间 备注(3,如果没有预留空间也会进入悲观插入流程
    ->判断是否需要加锁和开undo btr_cur_ins_lock_and_undo,此函数还会返回是否需要做锁继承的处理为输出参数inherit
      ->检查是否需要加锁lock_rec_insert_check_and_lock 插入印象锁就在这里
      ->记录undo trx_undo_report_row_operation
      ->更改row undo ptr指针row_upd_index_entry_sys_field
    ->做实际插入操作 page_cur_tuple_insert
      ->逻辑记录转换为物理记录 rec_convert_dtuple_to_rec
      ->获取每个字段的偏移量 rec_get_offsets
      ->进行实际插入 page_cur_insert_rec_low
        ->获取记录的实际大小
        ->寻找合适的位置进行插入,本步骤会找到合适的位置返回给insert_buf
          ->获取free链表的头部记录,注意只会检查第一个记录,不会做遍历,因此块中碎片是极有可能出现的
            只是innodb可以重组
          ->如果合适则使用
          ->不合适则返回
        ->进行记录创建拷贝 memcpy方式复制数据到insert_buf指向的位置,完成这一步记录加入到了块中 下面需要维护各种块信息  
        ->将记录加入到记录链表
        ->更新行的N_OWNER为0,以及设置heap_no
        ->设置块的一些最后修改属性如PAGE_DIRECTION、PAGE_N_DIRECTION、PAGE_LAST_INSERT
        ->更新slot的信息,可能涉及更改owner记录信息和owner记录的N_OWNER信息
        ->写redo信息 page_cur_insert_rec_write_log
      ->返回插入记录的offset
    ->进行AHI维护 btr_search_update_hash_on_insert/btr_search_update_hash_node_on_insert
    ->进行可能的锁的分裂 lock_update_insert 此处主要的判断是前面的输出参数inherit
    ->进行CHANGE BUFFER维护 ibuf_update_free_bits_if_full
  -> 如果成功修改最大事物ID PAGE_MAX_TRX_ID page_update_max_trx_id
  -> 返回结果
  • 备注1) 计算方式为 
    空页的容量 = 页大小(比如16K) - 页头大小(120) - 页尾大小(8) - 初始化2个槽大小(4=2*2) 
    实际的数据占用空间 = 已经分配数据空间的最大数据偏移量 - 页头大小(120) - 已经删除且purge的空间包含碎片空间 + 槽大小

然后用 
空页的容量 - 实际的数据占用空间=实际可用空间

因为页中难免会出现一些碎片,但是innodb的page拥有重新组织的能力,能够释放这部分空间。其重组函数为btr_page_reorganize_low

  • 备注2) 逻辑包含 
    如果包含碎片空间那么 
    -- 如果可用空间不足或者可用空间已经少于了重组块的设置BTR_CUR_PAGE_REORGANIZE_LIMIT(UNIV_PAGE_SIZE / 32)
    -- 记录数量大于1 
    -- 可用空间小于了插入记录的大小 
    否则 
    -- 可用空间小于了插入记录的大小

  • 备注3) 逻辑包含 
    --叶子结点 
    -- 主键 
    -- 记录大于两行 
    -- 剩余的空间 - 行的空间 < page_size/16 
    -- 分裂建议建议分裂

到此,相信大家对“insert进行第一次乐观插入逻辑分析”有了更深的了解,不妨来实际操作一番吧!这里是编程之家网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐