Mysql 内部结构(简)
引擎
InnoDb内存结构
内存结构包括Buffer Pool,Change Buffer,Adaptive Hash Index和Log buffer四块。
Buffer Pool
缓冲池,BP内部以Page为单位,默认为16K,BP底层采用链表管理Page,Innodb访问表记录和索引时会在Page中缓存,后续先缓存,未命中再IO。
Page分为Free page(空闲)、clean page(inserted的数据)和dirty page(updated,和磁盘不一致)。对应维护和管理的链接结构为free list(管理Free pagfe)、LRU list(管理clean page和 dirty page)和flush list(管理dirty page,内部按修改的时间顺序)
通过“show engine innodb status;”可查询内部结构(容量大小单位为page)
show variables like '%innodb_page_size%'; (select @@innodb_page_size)
LRU list(Latest Recent Used)
传统的LRU 算法才用链表以Used为维度来实现的。采用末尾淘汰。Innodb中的LRU稍微做了优化,加入了一个分界线(midpoint),mid之前的位置为new区(活跃),之后为old区(未活跃),避免扫表操作,空间比例为6:4(63:37),数据的new-old之间的移动,通过time(1秒)机制来回刷新。
show variables like '%innodb_old%';
show variables like '%innodb_buffer%'; innodb_buffer_pool_chunk_size参数为5.7开始新增的,旧的版本不能动态配置。pool_size = instances * chunk_size
Change Buffer
写缓存区。默认占Buffer pool的25%空间,最大为50%。
show variables like '%innodb_change_buffer_max_size%';
Log Buffer
日志缓冲区,用于保存要写入磁盘的log文件(redo/undo),log buffer会定期或空间满时自动刷新到磁盘上。 整个过程为Log buffer --> OS Cache --> 磁盘文件两步。可以通过设置'innodb_flush_log_at_trx_commit'参数控制日刷新行为。
show variables like '%innodb_log%';
默认1秒刷新一次日志文件,at_trx_commit值为0、1、2
0:每隔一秒写日志文件和刷盘操作。
1:事物提交后,立刻插即写日志文件和刷盘。
2:事物提交后,立刻写日志文件,每隔1秒进行刷盘操作。(推荐)。
磁盘结构
Mysql磁盘结构主要包括表空间和日志文件。
Namespace
系统表空间:包括数据字典、双写缓冲区、写缓冲和Undo logs。
独立表空间:创建表存在于独立表空间,通过设置innodb_file_per_table=on,开启使用独立的表空间。文件格式为.ibd。
通用表空间:也可存放数据表,创建表时指定的namespace ,会存放在通用表空间。
临时表空间:用户临时空间,mysql服务关闭后,会移除该空间。
undo表空间:5.7之后独立出来,旧版本存放于系统表空间中。
Mysql 8.0之后,磁盘做了很多调整,系统表空间里只有Chang buffer部分了。数据字典、双鞋缓冲区和Undo logs都有自己的独立表空间。