设为首页 收藏本站
查看: 637|回复: 0

[经验分享] 思考mysql内核之初级系列4--innodb缓冲区管理(摘自老杨)

[复制链接]

尚未签到

发表于 2016-10-23 10:28:22 | 显示全部楼层 |阅读模式
  我们在前面讨论了一些mysql的基础知识,现在将要开始进入innodb引擎,从这里开始我们将开始代码的结构分析,innodb的内容分析之后,将反过来分析查询优化引擎。今天,我们先来讨论innodb缓冲区管理。
文件:
D:\mysql-5.1.7-beta\storage\innobase\include\buf0buf.h
D:\mysql-5.1.7-beta\storage\innobase\buffer \buf0buf.c

Bingxi和alex开始交流innodb缓冲区结构(不考虑AWE的情况)。

Bingxi:“alex,咱们都知道所谓缓冲区就是将文件缓存,避免重复操作数据文件,这样可以有效地减少io。”
Alex:“是的,没错。缓冲区的大小是根据配置文件生成,配置文件中innodb_buffer_pool_size文件,除以16k就得到了对应的页面数。”
Bingxi:“嗯,是的。我们现在在debug的情况进行调试,显示的缓冲的页数为512页。也就是我们能够缓存的数据大小为512*16k=8M。这我们可以通过命令行来验证下。我们可以看到设置的大小为8388608,也就是8M,以16k一页计算,也就是512页。
mysql> show variables like 'innodb_buffer_pool_size';
+-------------------------+---------+
| Variable_name | Value |
+-------------------------+---------+
| innodb_buffer_pool_size | 8388608 |
+-------------------------+---------+
1 row in set (0.00 sec)
执行show innodb status\G;查看其中的片段。从中可以看出buffer pool size果然为512,不过呢,我怎么看到free buffers为493,也就是有19页是使用。这个就奇怪,我没有执行查询语句啊。
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 13244152; in additional pool allocated 176384
Buffer pool size 512
Free buffers 493
Database pages 19
Modified db pages 0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages read 19, created 0, written 0
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout

Alex:“因为innodb会有自己的一些系统表需要加载,也就是所谓的字典表。这个内容我们在以后讨论”
Bingxi:“嗯,好的,alex。咱们继续看buf0buf.h文件,我看buf_pool_struct是缓冲区的总结构。在其中记录了缓冲数据页管理、访问计数、LRU列表管理等等。我们先讨论下该结构的下面4个变量吧。
struct buf_pool_struct{
……
byte* frame_mem;
byte* frame_zero;
byte* high_end;
ulint n_frames;
……
};

Alex:“好吧,我们对着代码看吧。其实frame_mem就是分配的缓冲区的指针,但是这个指针不一定是16k对齐的,为了提升性能,进行了16k对齐,并将该值赋给frame_zero。high_end作为标识缓冲区的结尾。n_frames表示缓冲页的大小。
buf_pool_t*
buf_pool_init(
ulint max_size,
ulint curr_size,
ulint n_frames) //这三个值,在这里都是相等的。为了方便查看去掉了英文注释,建议对照代码
{
……

//果然buf_pool_t是全局缓冲区管理结构,分配全局值buf_pool
buf_pool = mem_alloc(sizeof(buf_pool_t));

……

//UNIV_PAGE_SIZE=16k,n_frames=512
//奇怪的是为什么分配了513个页,而不是512个页?
buf_pool->frame_mem = os_mem_alloc_large(
UNIV_PAGE_SIZE * (n_frames + 1),
TRUE, FALSE);

//如果分配失败,则返回
if (buf_pool->frame_mem == NULL) {

return(NULL);
}

//调整字节,也就16k字节对齐,也就是frame是16k的整数倍。
//如果buf_pool->frame_mem是16k的整数倍,那么frame=buf_pool->frame_mem
//否则frame>buf_pool->frame_mem and frame<buf_pool->frame_mem+16k,且frame能被frame整除
frame = ut_align(buf_pool->frame_mem, UNIV_PAGE_SIZE);

//frame作为缓冲区的起点
buf_pool->frame_zero = frame;
//buf_pool->high_end作为缓冲区的结尾
buf_pool->high_end = frame + UNIV_PAGE_SIZE * n_frames;
……


Bingxi:“我明白了,也缓冲的第0页的指针地址为frame_zero,第n页为frame_zero+n*16k(n从0开始)。”
Alex:“是的,是这样的。问你个问题,怎么知道这些数据缓冲页块当中哪些是空闲的,哪些是正在用的,哪些是被修改过的?”
Bingxi: “啊,我先看下代码。厄,我找到了,应该是另外一个结构体进行控制。从下面这个结构体中,我们可以看出,该结构指向了frame地址,也就是我们刚刚提到的缓冲页块。Space与offset标识着实际的硬盘文件,这样建立起来一个映射关系。也就是space与offset对应的硬盘页,映射到了frame缓冲块。因此在这里需要512(数据缓冲页块数量)个这样的结构。
/* The buffer control block structure */
struct buf_block_struct{
……
byte* frame; /* pointer to buffer frame which
……
ulint space; /* space id of the page */
ulint offset; /* page number within the space */
……
}

Alex:“是的,我们继续看buf_pool_init函数的代码片段,果然将第n个block与第n个frame进行关联。
buf_pool_t*
buf_pool_init(
ulint max_size,
ulint curr_size,
ulint n_frames) //为了方便讲解,这三个值,在这里都是相等的。为了方便查看去掉了英文注释,建议对照代码。差异性,留给读者去阅读。
{
……

//分配了512个控制块,这里正好一个控制块,控制一个数据缓冲页块。
buf_pool->blocks = ut_malloc(sizeof(buf_block_t) * max_size);

//如果分配失败则返回
if (buf_pool->blocks == NULL) {

return(NULL);
}

//对应每一个控制块进行赋予对应的缓冲页指针
//第n个对应的指针为buf_pool->frame_zero + i * UNIV_PAGE_SIZE
for (i = 0; i < max_size; i++) {

//这行代码等价于:block=i + buf_pool->blocks
block = buf_pool_get_nth_block(buf_pool, i);

frame = buf_pool->frame_zero + i * UNIV_PAGE_SIZE;

//通过另外一个数组管理block数组,这里可以不考虑
*(buf_pool->blocks_of_frames + i) = block;

//调用函数,将第n个block与第n个frame进行关联
buf_block_init(block, frame);

}
……

buf_block_init函数比较简单,我们跟踪进去看下。果然进行block与frame的关联了,但是呢,没有放入空闲列表。
static
void
buf_block_init(
/*===========*/
buf_block_t* block, /* in: pointer to control block */
byte* frame) /* in: pointer to buffer frame, or NULL if in
the case of AWE there is no frame */
{
block->state = BUF_BLOCK_NOT_USED;

//在这里进行block与frame的关联
block->frame = frame;

block->awe_info = NULL;

block->modify_clock = ut_dulint_zero;

block->file_page_was_freed = FALSE;

block->check_index_page_at_flush = FALSE;
block->index = NULL;

//特别注意这里,该块此时还没有放入空闲列表。
block->in_free_list = FALSE;
block->in_LRU_list = FALSE;

block->n_pointers = 0;

//创建锁
rw_lock_create(&(block->lock));
ut_ad(rw_lock_validate(&(block->lock)));

#ifdef UNIV_SYNC_DEBUG
rw_lock_create(&(block->debug_latch));
rw_lock_set_level(&(block->debug_latch), SYNC_NO_ORDER_CHECK);
#endif /* UNIV_SYNC_DEBUG */
}

Bingxi:“哈哈,alex,你弱了吧。你再看看,在buf_pool_init函数中紧跟着就将这些block放入了空闲列表。
buf_pool_t*
buf_pool_init(
ulint max_size,
ulint curr_size,
ulint n_frames) //这三个值,在这里都是相等的。为了方便查看去掉了英文注释,建议对照代码
{
……

for (i = 0; i < curr_size; i++) {
//获得第n个block
block = buf_pool_get_nth_block(buf_pool, i);

if (block->frame) {

//添加到空闲列表
UT_LIST_ADD_LAST(free, buf_pool->free, block);
//并设置in_free_list状态为真
block->in_free_list = TRUE;
}
……


Alex:“嗯,差不多,就先打住了,也该睡觉了。”
Bingxi:“ok,晚安。”
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-290161-1-1.html 上篇帖子: java mysql数据库乱码问题——写代码一定要细心,不然会郁闷死的 下篇帖子: MySQL源码学习:关于慢查询日志中的Rows_examined=0
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表