一个Page从磁盘读入buffer pool的过程

一个Page从磁盘读入buffer pool的过程

以下是边看代码边记录的,从磁盘读取一个压缩Pagebuffer pool的的全过程,以函数buf_page_get_gen作为入口(基于MySQL5.7.31

|-buf_page_get_gen

(如果请求的数据页已经在Buffer Pool中了,修改相应信息后,就直接返回对应数据页指针,如果Buffer Pool中没有相关数据页,则从磁盘中读取。)

      |-buf_pool_t* buf_pool = buf_pool_get(page_id);

             |- ulint             ignored_page_no = page_id.page_no() >> 6;

               page_id_t          id(page_id.space(), ignored_page_no);

                 ulint                 i = id.fold() % srv_buf_pool_instances;

(依据space_id和page_no查找指定的数据页在哪个Buffer Pool Instance里面。这里有个小细节,page_no的第六位被砍掉,这是为了保证一个extent的数据能被缓存到同一个Buffer Pool Instance中,便于后面的预读操作。)

      |-block = (buf_block_t*) buf_page_hash_get_low(buf_pool, page_id);

(在page hash中查找这个数据页是否已经被加载到对应的Buffer Pool Instance中)

       |-if (block == NULL)

                  if (mode == BUF_GET_IF_IN_POOL_OR_WATCH)

(如果没有找到这个数据页且mode为BUF_GET_IF_IN_POOL_OR_WATCH则设置watch数据页(buf_pool_watch_set))

                                 if (mode == BUF_GET_IF_IN_POOL|| mode == BUF_PEEK_IF_IN_POOL

                                            || mode == BUF_GET_IF_IN_POOL_OR_WATCH)

(如果没有找到数据页且mode为BUF_GET_IF_IN_POOL、BUF_PEEK_IF_IN_POOL或者BUF_GET_IF_IN_POOL_OR_WATCH函数直接返回空,表示没有找到数据页。)

     |-buf_read_page(page_id, page_size)

(如果没有找到数据但是mode为其他,就从磁盘中同步读取(buf_read_page)。)

            |-count = buf_read_page_low(&err, true,

                  0, BUF_READ_ANY_PAGE, page_id, page_size, false);

                       |-bpage = buf_page_init_for_read(err, mode, page_id, page_size, unzip);

                                  |-block = buf_LRU_get_free_block(buf_pool);

(在读取磁盘数据之前,我们如果发现需要读取的是非压缩页,则先从Free List中获取空闲的数据页,如果Free List中已经没有了,则需要通过刷脏来释放数据页)

                                             |-buf_LRU_check_size_of_non_data_objects(buf_pool);

(统计Free List和LRU List的长度,如果发现他们再Buffer Chunks占用太少的空间,则表示太多的空间被行锁,自使用哈希等内部结构给占用了,一般这些都是大事务导致的。这时候会给出报警。)

                                            |-block = buf_LRU_get_free_only(buf_pool);

(查看Free List中是否还有空闲的数据页,如果有则直接返回,否则进入下一步。大多数情况下,这一步都能找到空闲的数据页。)

                                             |-freed=buf_LRU_scan_and_free_block(buf_pool,n_iterations > 0);

                  (如果Free List中已经没有空闲的数据页了,则会尝试驱逐LRU List末尾的数据页)

                                                        

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值