思考mysql内核之初级系列4innodb缓冲区管理.docx

上传人:b****0 文档编号:17788698 上传时间:2023-08-03 格式:DOCX 页数:9 大小:17.64KB
下载 相关 举报
思考mysql内核之初级系列4innodb缓冲区管理.docx_第1页
第1页 / 共9页
思考mysql内核之初级系列4innodb缓冲区管理.docx_第2页
第2页 / 共9页
思考mysql内核之初级系列4innodb缓冲区管理.docx_第3页
第3页 / 共9页
思考mysql内核之初级系列4innodb缓冲区管理.docx_第4页
第4页 / 共9页
思考mysql内核之初级系列4innodb缓冲区管理.docx_第5页
第5页 / 共9页
思考mysql内核之初级系列4innodb缓冲区管理.docx_第6页
第6页 / 共9页
思考mysql内核之初级系列4innodb缓冲区管理.docx_第7页
第7页 / 共9页
思考mysql内核之初级系列4innodb缓冲区管理.docx_第8页
第8页 / 共9页
思考mysql内核之初级系列4innodb缓冲区管理.docx_第9页
第9页 / 共9页
亲,该文档总共9页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

思考mysql内核之初级系列4innodb缓冲区管理.docx

《思考mysql内核之初级系列4innodb缓冲区管理.docx》由会员分享,可在线阅读,更多相关《思考mysql内核之初级系列4innodb缓冲区管理.docx(9页珍藏版)》请在冰点文库上搜索。

思考mysql内核之初级系列4innodb缓冲区管理.docx

思考mysql内核之初级系列4innodb缓冲区管理

思考mysql内核之初级系列4--innodb缓冲区管理

我们在前面讨论了一些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>showvariableslike'innodb_buffer_pool_size';

+-------------------------+---------+

|Variable_name|Value|

+-------------------------+---------+

|innodb_buffer_pool_size|8388608|

+-------------------------+---------+

1rowinset(0.00sec)

执行showinnodbstatus\G;查看其中的片段。

从中可以看出bufferpoolsize果然为512,不过呢,我怎么看到freebuffers为493,也就是有19页是使用。

这个就奇怪,我没有执行查询语句啊。

----------------------

BUFFERPOOLANDMEMORY

----------------------

Totalmemoryallocated13244152;inadditionalpoolallocated176384

Bufferpoolsize512

Freebuffers493

Databasepages19

Modifieddbpages0

Pendingreads0

Pendingwrites:

LRU0,flushlist0,singlepage0

Pagesread19,created0,written0

0.00reads/s,0.00creates/s,0.00writes/s

Nobufferpoolpagegetssincethelastprintout

Alex:

“因为innodb会有自己的一些系统表需要加载,也就是所谓的字典表。

这个内容我们在以后讨论”

Bingxi:

“嗯,好的,alex。

咱们继续看buf0buf.h文件,我看buf_pool_struct是缓冲区的总结构。

在其中记录了缓冲数据页管理、访问计数、LRU列表管理等等。

我们先讨论下该结构的下面4个变量吧。

structbuf_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_memandframeframe_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(数据缓冲页块数量)个这样的结构。

/*Thebuffercontrolblockstructure*/

structbuf_block_struct{

……

byte*frame;/*pointertobufferframewhich

……

ulintspace;/*spaceidofthepage*/

ulintoffset;/*pagenumberwithinthespace*/

……

}

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

//这行代码等价于:

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:

pointertocontrolblock*/

byte*frame)/*in:

pointertobufferframe,orNULLifin

thecaseofAWEthereisnoframe*/

{

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)));

#ifdefUNIV_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

//获得第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,晚安。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2