转载请附原文链接:http://www.cnblogs.com/wingsless/p/5582063.html

昨天写到了InnoDB缓冲池的预读:《InnoDB源码分析--缓冲池(二)》,最后因为着急看欧洲杯,没有把线性预读写完,今天接着写。

线性预读是由这个函数实现的:buf_read_ahead_linear,和随机预读一样,首先是要确定区域边界,这个边界内被访问过的page如果达到一个阈值(BUF_READ_AHEAD_LINEAR_THRESHOLD),就会触发预读操作。边界的算法由BUF_READ_AHEAD_LINEAR_AREA决定:

    low  = (offset / BUF_READ_AHEAD_LINEAR_AREA)
* BUF_READ_AHEAD_LINEAR_AREA;
high = (offset / BUF_READ_AHEAD_LINEAR_AREA + )
* BUF_READ_AHEAD_LINEAR_AREA; if ((offset != low) && (offset != high - )) {
/* This is not a border page of the area: return */ return();
}

注意,如果offset不在边界上,就不会进行预读了,这一点和随机预读是不一样的。线性预读其实是顺序性读取的,如果offset在low位置,逆序读取page,如果offset在high位置,正序读取page。读取的每个页,都要进行判断,如果被访问过的页的数量到达上面提到的阈值,就满足了线性预读的条件,达不到阈值,就不进行预读,代码如下:

    asc_or_desc = ; //默认正序

    if (offset == low) {
asc_or_desc = -; //如果offset在low位置,变成逆序
} fail_count = ; for (i = low; i < high; i++) {
block = buf_page_hash_get(space, i); //遍历边界范围内的页 if ((block == NULL) || !block->accessed) {
/* Not accessed */
fail_count++; //未读取的页计数 } else if (pred_block
&& (ut_ulint_cmp(block->LRU_position,
pred_block->LRU_position)
!= asc_or_desc)) {
/* Accesses not in the right order */ fail_count++;
pred_block = block;
}
} if (fail_count > BUF_READ_AHEAD_LINEAR_AREA
- BUF_READ_AHEAD_LINEAR_THRESHOLD) { //不满足预读条件,退出
/* Too many failures: return */ mutex_exit(&(buf_pool->mutex)); return();
}

我之前在一本书上看到过一句话,大概意思是内存里的页可以不是物理上连续的,逻辑上却是连续的。这里的线性预读要求这些页在物理上也是必须连续的:

    pred_offset = fil_page_get_prev(frame);
succ_offset = fil_page_get_next(frame); mutex_exit(&(buf_pool->mutex)); if ((offset == low) && (succ_offset == offset + )) { /* This is ok, we can continue */
new_offset = pred_offset; //满足了条件,继续 } else if ((offset == high - ) && (pred_offset == offset - )) { /* This is ok, we can continue */
new_offset = succ_offset; //这是正序情况下,满足条件
} else {
/* Successor or predecessor not in the right order */ return();
}

这个地方是这样的,首先利用fil_page_get_prev和fil_page_get_next函数读取offset->frame之后或者之前的4个bytes,如果结果满足顺序条件,可以继续进行线性预读。

    for (i = low; i < high; i++) {
/* It is only sensible to do read-ahead in the non-sync
aio mode: hence FALSE as the first parameter */ if (!ibuf_bitmap_page(i)) {
count += buf_read_page_low(
&err, FALSE,
ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
space, tablespace_version, i);
if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Warning: in"
" linear readahead trying to access\n"
"InnoDB: tablespace %lu page %lu,\n"
"InnoDB: but the tablespace does not"
" exist or is just being dropped.\n",
(ulong) space, (ulong) i);
}
}
}

线性预读还是利用了buf_read_page_low函数,这一点和随机预读一样,而且是异步方式。

至此便完成了线性预读。

不管是随机预读还是线性预读,都会有一些条件不进行预读,比如系统压力大的时候不预读,这个的实现:

    if (buf_pool->n_pend_reads
> buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
mutex_exit(&(buf_pool->mutex)); return();
}

这里规定了pend读取数大于buf_pool->curr_size一半的时候,就不预读了,相似的还有很多条件,都在代码里,这里就不写了。

InnoDB源码分析--缓冲池(三)的更多相关文章

  1. InnoDB源码分析--缓冲池(二)

    转载请附原文链接:http://www.cnblogs.com/wingsless/p/5578727.html 上一篇中我简单的分析了一下InnoDB缓冲池LRU算法的相关源码,其实说不上是分析,应 ...

  2. innoDB源码分析--缓冲池

    最开始学Oracle的时候,有个概念叫SGA和PGA,是非常重要的概念,其实就是内存中的缓冲池.InnoDB的设计类似于Oracle,也会在内存中开辟一片缓冲池.众所周知,CPU的速度和磁盘的IO速度 ...

  3. 一个普通的 Zepto 源码分析(三) - event 模块

    一个普通的 Zepto 源码分析(三) - event 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核心模块, ...

  4. Koa源码分析(三) -- middleware机制的实现

    Abstract 本系列是关于Koa框架的文章,目前关注版本是Koa v1.主要分为以下几个方面: Koa源码分析(一) -- generator Koa源码分析(二) -- co的实现 Koa源码分 ...

  5. Spring MVC源码分析(三):SpringMVC的HandlerMapping和HandlerAdapter的体系结构设计与实现

    概述在我的上一篇文章:Spring源码分析(三):DispatcherServlet的设计与实现中提到,DispatcherServlet在接收到客户端请求时,会遍历DispatcherServlet ...

  6. Backbone源码分析(三)

    Backbone源码分析(一) Backbone源码分析(二) Backbone中主要的业务逻辑位于Model和Collection,上一篇介绍了Backbone中的Model,这篇文章中将主要探讨C ...

  7. 二维码扫描 zxing源码分析(三)result、history部分

    前两个部分的地址是:ZXING源码分析(一)CAMERA部分  . zxing源码分析(二)decode部分 下面我们来看第三部分 result包下面有很多的类,其中的核心类是 com.google. ...

  8. Java集合源码分析(三)Vevtor和Stack

    前言 前面写了一篇关于的是LinkedList的除了它的数据结构稍微有一点复杂之外,其他的都很好理解的.这一篇讲的可能大家在开发中很少去用到.但是有的时候也可能是会用到的! 注意在学习这一篇之前,需要 ...

  9. Spark RPC框架源码分析(三)Spark心跳机制分析

    一.Spark心跳概述 前面两节中介绍了Spark RPC的基本知识,以及深入剖析了Spark RPC中一些源码的实现流程. 具体可以看这里: Spark RPC框架源码分析(二)运行时序 Spark ...

随机推荐

  1. [javaSE] 反射-动态加载类

    Class.forName(“类的全称”) ①不仅表示了类的类类型,还代表了动态加载类 ②请大家区分编译,运行 ③编译时刻加载类是静态加载类,运行时刻加载类是动态加载类 Ⅰ所有的new对象都是静态加载 ...

  2. GIT 查看/修改用户名和邮箱地址

    用户名和邮箱地址的作用用户名和邮箱地址是本地git客户端的一个变量,不随git库而改变.每次commit都会用用户名和邮箱纪录.github的contributions统计就是按邮箱来统计的.查看用户 ...

  3. 关于线上的bug什么时候修复的思考

    这里系统专门指的是那种用户量大的系统,比如有几百万或者上千万的注册会员.因为小系统因为用户量少,不存在这种思考,考虑有时候是多余的.另外还有内部系统,给自己公司内部人员使用的,即便是出现了问题,也不会 ...

  4. maven url

    aliyun阿里云Maven仓库地址--加速你的maven构建   maven仓库用过的人都知道,国内有多么的悲催.还好有比较好用的镜像可以使用,尽快记录下来.速度提升100倍. http://mav ...

  5. mysql 导入text 到数据库

    load data local infile 'f:/PhoneLocation_201601.327665.txt' into table sys_t_phone_area fields termi ...

  6. [Android] WebView内的本地网页,使用XMLHttpRequest读取本地档案

    [Android] WebView内的本地网页,使用XMLHttpRequest读取本地档案 问题情景 在Android里,可以使用WebView来呈现本地或是远程的网页内容.但是在显示本地网页时,如 ...

  7. Test your application

    Creating automatic test suites for your application is a good way to make it robust. It allows you t ...

  8. reset

    html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, ...

  9. html 网页文本设计

    1.文本的排版 1.1 <body> <h2>李白</h2> <p align="center" > <font face=& ...

  10. H5移动端页面设计心得分享

    去年JDC出了不少优秀的武媚娘…不,H5呢,大家都很拼,同时当然也积累了一些经验和教训,今天结合咱们的实战案例,从字体,排版,动效,音效,适配性,想法这几个方面好好聊一聊关于H5的设计,希望对同学们有 ...