InnoDB源码分析--缓冲池(三)
转载请附原文链接: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源码分析--缓冲池(三)的更多相关文章
- InnoDB源码分析--缓冲池(二)
转载请附原文链接:http://www.cnblogs.com/wingsless/p/5578727.html 上一篇中我简单的分析了一下InnoDB缓冲池LRU算法的相关源码,其实说不上是分析,应 ...
- innoDB源码分析--缓冲池
最开始学Oracle的时候,有个概念叫SGA和PGA,是非常重要的概念,其实就是内存中的缓冲池.InnoDB的设计类似于Oracle,也会在内存中开辟一片缓冲池.众所周知,CPU的速度和磁盘的IO速度 ...
- 一个普通的 Zepto 源码分析(三) - event 模块
一个普通的 Zepto 源码分析(三) - event 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核心模块, ...
- Koa源码分析(三) -- middleware机制的实现
Abstract 本系列是关于Koa框架的文章,目前关注版本是Koa v1.主要分为以下几个方面: Koa源码分析(一) -- generator Koa源码分析(二) -- co的实现 Koa源码分 ...
- Spring MVC源码分析(三):SpringMVC的HandlerMapping和HandlerAdapter的体系结构设计与实现
概述在我的上一篇文章:Spring源码分析(三):DispatcherServlet的设计与实现中提到,DispatcherServlet在接收到客户端请求时,会遍历DispatcherServlet ...
- Backbone源码分析(三)
Backbone源码分析(一) Backbone源码分析(二) Backbone中主要的业务逻辑位于Model和Collection,上一篇介绍了Backbone中的Model,这篇文章中将主要探讨C ...
- 二维码扫描 zxing源码分析(三)result、history部分
前两个部分的地址是:ZXING源码分析(一)CAMERA部分 . zxing源码分析(二)decode部分 下面我们来看第三部分 result包下面有很多的类,其中的核心类是 com.google. ...
- Java集合源码分析(三)Vevtor和Stack
前言 前面写了一篇关于的是LinkedList的除了它的数据结构稍微有一点复杂之外,其他的都很好理解的.这一篇讲的可能大家在开发中很少去用到.但是有的时候也可能是会用到的! 注意在学习这一篇之前,需要 ...
- Spark RPC框架源码分析(三)Spark心跳机制分析
一.Spark心跳概述 前面两节中介绍了Spark RPC的基本知识,以及深入剖析了Spark RPC中一些源码的实现流程. 具体可以看这里: Spark RPC框架源码分析(二)运行时序 Spark ...
随机推荐
- Firemonkey 指定 StringGrid 只能上下滾动,不要左右滚动
要使 StringGrid 只能上下滚动,不要左右滚动,只要加入下面代码即可: StringGrid1.AniCalculations.TouchTracking := [ttVertical]; p ...
- Facebook的Hack语言三大看点
Hack语言主要有三大看点:类型化.异步.集合. Hack最基础的特性就是类型标注.PHP5已经开始支持对象的类型化,PHP7也提供了标量类型化声明.Hack提供了全面的类型标注支持,与其typech ...
- 用java实现新浪爬虫,代码完整剖析(仅针对当前SinaSignOn有效)
先来看我们的web.xml文件,如下 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application ...
- 2016年湖南省第十二届大学生计算机程序设计竞赛Problem A 2016 找规律归类
Problem A: 2016 Time Limit: 5 Sec Memory Limit: 128 MB Description 给出正整数 n 和 m,统计满足以下条件的正整数对 (a,b) ...
- Java集合源码分析(二)ArrayList
ArrayList简介 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境下,多线 ...
- [小北De编程手记] : Lesson 06 玩转 xUnit.Net 之 定义自己的FactAttribute
xUnit.Net本身提供了标记测试方法的标签Fact和Theory.在前面的文章<Lesson 02 玩转 xUnit.Net 之 基本UnitTest & 数据驱动>中,也对它 ...
- Nodejs与ES6系列1:变量声明
1.声明变量 在JS当中一个变量的作用域(scope)是程序中定义这个变量的区域.变量分为两类,全局(global)的和局部的.其中全局变量的作用域是全局性的,即在JavaScript代码中,它处处都 ...
- CSS常用样式(四)之animation
上篇CSS常用样式(三)这篇博文中已经介绍过了CSS中具有动画效果的transition.transform,今天来大概说说CSS中的animation.animation的加入会使得动画效果更加乐观 ...
- SharePoint 2013 搜索报错"Unable to retrieve topology component health. This may be because the admin component is not up and running"
环境描述 Windows 2012 R2,SharePoint 2013(没有sp1补丁),sql server 2012 错误描述 搜索服务正常,但是爬网一直在Crawling Full,但是爬不到 ...
- 你真的了解UITextField吗?
一:首先查看一下关于UITextField的定义 NS_CLASS_AVAILABLE_IOS(2_0) @interface UITextField : UIControl <UITextIn ...