我们在前面讨论了一些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 size512

Free buffers493

Database pages19

Modified db pages0

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;

ulintn_frames;

……

};

Alex:“好吧,我们对着代码看吧。其实frame_mem就是分配的缓冲区的指针,但是这个指针不一定是16k对齐的,为了提升性能,进行了16k对齐,并将该值赋给frame_zero。high_end作为标识缓冲区的结尾。n_frames表示缓冲页的大小。

buf_pool_t*

buf_pool_init(

ulintmax_size,

ulintcurr_size,

ulintn_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 frameframe_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

……

ulintspace;/* space id of the page */

ulintoffset;/* page number within the space */

……

}

Alex:“是的,我们继续看buf_pool_init函数的代码片段,果然将第n个block与第n个frame进行关联。

buf_pool_t*

buf_pool_init(

ulintmax_size,

ulintcurr_size,

ulintn_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(

ulintmax_size,

ulintcurr_size,

ulintn_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,晚安。”

分享到:

2010-10-27 11:31

浏览 550

评论

mysql++缓冲区_思考mysql内核之初级系列4--innodb缓冲区管理(摘自老杨)相关推荐

  1. Mysql运行在内核空间_思考mysql内核之初级系列6—innodb文件管理 | 学步园

    在上一篇里面,bingxi和alex思考了information_schema,这个一直在innodb外围打转.没有进入到innodb的内部.在后续的文章中,以innodb的为主,逐个思考.Bingx ...

  2. 阿里云查看mysql版本_查看mysql版本

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  3. 简易mysql优化_优化 MySQL:简单三个技巧

    原标题:优化 MySQL:简单三个技巧 技巧#1:为临时表分配足够的内存 在某些情况下,服务器在处理语句时会创建内部临时表.临时表用于内部操作如GROUP BY和distinct,还有一些ORDER ...

  4. mysql整备_【mysql】使用xtrabackup在线增量备份及恢复数据库

    一.Percona Xtrabackup 简介 1.Xtrabackup  bin目录文件 介绍 1)innobackupex innobackupex 是xtrabackup的一个符号链接 . in ...

  5. shell实行mysql语句_【Mysql】shell运行mysql的sql语句_MySQL

    bitsCN.com [Mysql]shell运行mysql的sql语句 shell本身是一种脚本语言,所以不能像java一样通过api去连接数据库.shell还是要借助mysql本身的一些运行脚本才 ...

  6. mysql 优化_常用MySQL优化

    1.大批量插入数据优化 (1)对于MyISAM存储引擎的表,可以使用:DISABLE KEYS 和 ENABLE KEYS 用来打开或者关闭 MyISAM 表非唯一索引的更新. ALTER TABLE ...

  7. 阿里云查看mysql版本_查看mysql版本的四种方法及常用命令

    [shengting@login ~]$ mysql -V mysql Ver 14.7 Distrib 4.1.10a, for redhat-linux-gnu (i686) 2:在mysql中: ...

  8. 涂抹mysql 完整_涂抹mysql笔记-管理mysql服务

    $ /mysql/scripts/mysql_install_db --datadir=/mysql/data --basedir=/mysql support-files/mysql.server脚 ...

  9. xshell安装mysql步骤_数据库Mysql与禅道安装

    一.Linux上搭建禅道 Mysql 是关系型数据库管理系统 1.下载安装包:将安装包直接解压到/opt目录下,不要 解压到别的目录在拷贝到/opt/,因为这样会导致文件的所有者和读写权限改变 2.解 ...

  10. mysql实时读写_[DataBase] MySql 查看实时日志

    MySql 查看实时日志 -f 代表会实时读取该文件的更新内容 tail -f /usr/local/mysql/log/mysql.log 配置好日志 [mysqld] log-error = /u ...

最新文章

  1. java中countinue,.random(用于产生一个随机数)入门可看
  2. oracle12c spa,Oracle12c功能加强 新特性之管理功能的加强
  3. WinDbg配置和使用基础
  4. 嵌入式Linux教程:安装VMware Tools VMware Tools显示灰色解决方法
  5. linux 0x00,linux 学习笔记0x00
  6. Vista操作系统评估参考资料
  7. Hydra暴力破解工具的用法
  8. EF--Code First配置问题
  9. 在从1到n的正数中1出现的次数
  10. SpriteKit在复制节点时留了一个巨坑给开发者,需要开发者手动把复制节点的isPaused设置为false...
  11. sql创建表主键gui_在SQL Server中使用主数据服务快速创建最终用户可以维护的GUI
  12. 冬日暖阳!网易大数据应用与分析实践分享沙龙【北京站 12.16】
  13. 二维凸包算法(Andrew算法)
  14. java计算机毕业设计BS景区票务管理系统设计与实现源码+mysql数据库+系统+lw文档+部署
  15. php网站banner图片切换,最简单的Banner轮播左右切换效果代码及实现思路(附带源码)...
  16. 视频号里的视频怎么保存到本地
  17. python生存曲线_用户行为与生存分析
  18. 日本使用ips细胞制作“类器官”的最新进展
  19. 在 MySQL 数据库中删除重复记录的步骤
  20. stm8l051 halt之后外部中断唤醒问题

热门文章

  1. 线性表_双向循环链表(Caesar加密变换结点顺序 代码实现 )
  2. 血压预测常用数据集整理
  3. opencv鼠标回调函数实现ROI区域像素值相同化
  4. springcloud---how2java--记录零碎的信息
  5. .net 中使用rabbitmq
  6. javascript判断给定字符串是否是回文
  7. 【学堂在线数据挖掘:理论方法笔记】第五天(3.29)
  8. 【Matlab学习笔记】【函数学习】nargin 参数
  9. 基于阈值分解的多级中值滤波-附代码
  10. leetcode刷题日记-leetcode刷题日记-71. 简化路径