mysqlinnodb存储的⽂件结构_MySQLInnoDB存储引擎
(⼀):精谈innod。。。
精谈innodb的存储结构
前⾔
MySQL存储引擎
InnoDB和MyISAM对⽐
InnoDB存储结构
InnoDB内存结构
Buffer Pool
Change Buffer
Adaptive Hash Index
Log Buffer
InnoDB磁盘结构
表空间(Tablespaces)
数据字典(InnoDB Data Dictionary)
双写缓冲区(Doublewrite Buffer)
重做⽇志(Redo Log)
撤销⽇志(Undo Logs)
新版本结构演变
总结
前⾔
虽然写者写过⼀期关于innodb的储存结构和b+树索引,但当时了解太少,所以理解和表达都很浅显,经过⼀段漫长时间的研究,对innodb 的存储引擎也了解更多⼀些,所以来分享给⼤家。
MySQL存储引擎
存储引擎在MySQL的体系架构中位于第三层,负责MySQL中的数据的存储和提取,是与⽂件打交道的⼦系统,它是根据MySQL提供的⽂件访问层抽象接⼝定制的⼀种⽂件访问机制,这种机制就叫作存储引擎。
使⽤show engines命令,就可以查看当前数据库⽀持的引擎信息。
在5.5版本之前默认采⽤MyISAM存储引擎,从5.5开始采⽤InnoDB存储引擎。
InnoDB:⽀持事务,具有提交,回滚和崩溃恢复能⼒,事务安全
MyISAM:不⽀持事务和外键,访问速度快
Memory:利⽤内存创建表,访问速度⾮常快,因为数据在内存,⽽且默认使⽤Hash索引,但是⼀旦关闭,数据就会丢失
Archive:归档类型引擎,仅能⽀持insert和select语句
Csv:以CSV⽂件进⾏数据存储,由于⽂件限制,所有列必须强制指定not null,另外CSV引擎也不⽀持索引和分区,适合做数据交换的中间表
mysql存储文档BlackHole: ⿊洞,只进不出,进来消失,所有插⼊数据都不会保存
Federated:可以访问远端MySQL数据库中的表。⼀个本地表,不保存数据,访问远程表内容
MRG_MyISAM:⼀组MyISAM表的组合,这些MyISAM表必须结构相同,Merge表本⾝没有数据,对Merge操作可以对⼀组MyISAM表进⾏操作。
InnoDB和MyISAM对⽐
InnoDB和MyISAM是使⽤MySQL时最常⽤的两种引擎类型,我们重点来看下两者区别。
事务和外键
InnoDB⽀持事务和外键,具有安全性和完整性,适合⼤量insert或update操作
MyISAM不⽀持事务和外键,它提供⾼速存储和检索,适合⼤量的select查询操作
锁机制
InnoDB⽀持⾏级锁,锁定指定记录。基于索引来加锁实现。
MyISAM⽀持表级锁,锁定整张表。
索引结构
InnoDB使⽤聚集索引(聚簇索引),索引和记录在⼀起存储,既缓存索引,也缓存记录。
MyISAM使⽤⾮聚集索引(⾮聚簇索引),索引和记录分开。
MyISAM使⽤表锁,会导致写操作并发率低,读之间并不阻塞,读写阻塞。
InnoDB读写阻塞可以与隔离级别有关,可以采⽤多版本并发控制(MVCC)来⽀持⾼并发
存储⽂件
InnoDB表对应两个⽂件,⼀个.frm表结构⽂件,⼀个.ibd数据⽂件。InnoDB表最⼤⽀持64TB;
MyISAM表对应三个⽂件,⼀个.frm表结构⽂件,⼀个MYD表数据⽂件,⼀个.MYI索引⽂件。从MySQL5.0开始默认限制是256TB。
适⽤场景
MyISAM
不需要事务⽀持(不⽀持)
并发相对较低(锁定机制问题)
数据修改相对较少,以读为主
数据⼀致性要求不⾼
InnoDB
需要事务⽀持(具有较好的事务特性)
⾏级锁定对⾼并发有很好的适应能⼒
数据更新较为频繁的场景
数据⼀致性要求较⾼
硬件设备内存较⼤,可以利⽤InnoDB较好的缓存能⼒来提⾼内存利⽤率,减少磁盘IO
InnoDB存储结构
从MySQL 5.5版本开始默认使⽤InnoDB作为引擎,它擅长处理事务,具有⾃动崩溃恢复的特性,在⽇常开发中使⽤⾮常⼴泛。下⾯是官⽅的InnoDB引擎架构图,主要分为内存结构和磁盘结构两⼤部分
InnoDB内存结构
内存结构主要包括Buffer Pool、Change Buffer、Adaptive Hash Index和Log Buffer四⼤组件。
缓冲池,简称BP。BP以Page页为单位,默认⼤⼩16K,BP的底层采⽤链表数据结构管理Page。在InnoDB访问表记录和索引时会在Page 页中缓存,以后使⽤可以减少磁盘IO操作,提升效率。
Page管理机制
Page根据状态可以分为三种类型:
free page : 空闲page,未被使⽤
clean page:被使⽤page,数据没有被修改过
dirty page:脏页,被使⽤page,数据被修改过,页中数据和磁盘的数据产⽣了不⼀致
针对上述三种page类型,InnoDB通过三种链表结构来维护和管理:
free list :表⽰空闲缓冲区,管理free page
flush list:表⽰需要刷新到磁盘的缓冲区,管理dirty page,内部page按修改时间排序。脏页即存在于flush链表,也在LRU链表中,但是两种互不影响,LRU链表负责管理page的可⽤性和释放,⽽flush链表负责管理脏页的刷盘操作。
lru list:表⽰正在使⽤的缓冲区,管理clean page和dirty page,缓冲区以midpoint为基点,前⾯链表称为new列表区,存放经常访问的数据,占63%;后⾯的链表称为old列表区,存放使⽤较少数据,占37%。
改进型LRU算法维护
普通LRU:末尾淘汰法,新数据从链表头部加⼊,释放空间时从末尾淘汰
改性LRU:链表分为new和old两个部分,加⼊元素时并不是从表头插⼊,⽽是从中间midpoint位置插⼊,如果数据很快被访问,那么page 就会向new列表头部移动,如果数据没有被访问,会逐步向old尾部移动,等待淘汰。
每当有新的page数据读取到buffer pool时,InnoDb引擎会判断是否有空闲页,是否⾜够,如果有就将free page从free list列表删除,放⼊到LRU列表中。没有空闲页,就会根据LRU算法淘汰LRU链表默认的页,将内存空间释放分配给新的页。
Buffer Pool配置参数
show variables like ‘%innodb_page_size%’; //查看page页⼤⼩
show variables like ‘%innodb_old%’; //查看lru list中old列表参数
show variables like ‘%innodb_buffer%’; //查看buffer pool参数
建议:将innodb_buffer_pool_size设置为总内存⼤⼩的60%-80%,innodb_buffer_pool_instances可以设置为多个,这样可以避免缓存争夺。
Change Buffer
写缓冲区,简称CB。在进⾏DML操作时,如果BP没有其相应的Page数据,并不会⽴刻将磁盘页加载到缓冲池,⽽是在CB记录缓冲变更,等未来数据被读取时,再将数据合并恢复到BP中。
ChangeBuffer占⽤BufferPool空间,默认占25%,最⼤允许占50%,可以根据读写业务量来进⾏调整。参数
innodb_change_buffer_max_size;
当更新⼀条记录时,该记录在BufferPool存在,直接在BufferPool修改,⼀次内存操作。如果该记录在BufferPool不存在(没有命中),会直接在ChangeBuffer进⾏⼀次内存操作,不⽤再去磁盘查询数据,避免⼀次磁盘IO。当下次查询记录时,会先进性磁盘读取,然后再从ChangeBuffer中读取信息合并,最终载⼊BufferPool中。
写缓冲区,仅适⽤于⾮唯⼀普通索引页,为什么?
如果在索引设置唯⼀性,在进⾏修改时,InnoDB必须要做唯⼀性校验,因此必须查询磁盘,做⼀次IO操作。会直接将记录查询到BufferPool中,然后在缓冲池修改,不会在ChangeBuffer操作。
Adaptive Hash Index
⾃适应哈希索引,⽤于优化对BP数据的查询。InnoDB存储引擎会监控对表索引的查,如果观察到建⽴哈希索引可以带来速度的提升,则建⽴哈希索引,所以称之为⾃适应。InnoDB存储引擎会⾃动根据访问的频率和模式来为某些页建⽴哈希索引。
Log Buffer
⽇志缓冲区,⽤来保存要写⼊磁盘上log⽂件(Redo/Undo)的数据,⽇志缓冲区的内容定期刷新到磁盘log⽂件中。⽇志缓冲区满时会⾃动将其刷新到磁盘,当遇到BLOB或多⾏更新的⼤事务操作时,增加⽇志缓冲区可以节省磁盘I/O。
LogBuffer主要是⽤于记录InnoDB引擎⽇志,在DML操作时会产⽣Redo和Undo⽇志。
LogBuffer空间满了,会⾃动写⼊磁盘。可以通过将innodb_log_buffer_size参数调⼤,减少磁盘IO频率
innodb_flush_log_at_trx_commit参数控制⽇志刷新⾏为,默认为1
0 : 每隔1秒写⽇志⽂件和刷盘操作(写⽇志⽂件LogBuffer–>OS cache,刷盘OScache–>磁盘⽂件),最多丢失1秒数据
1:事务提交,⽴刻写⽇志⽂件和刷盘,数据不丢失,但是会频繁IO操作
2:事务提交,⽴刻写⽇志⽂件,每隔1秒钟进⾏刷盘操作
InnoDB磁盘结构
InnoDB磁盘主要包含Tablespaces,InnoDB Data Dictionary,Doublewrite Buffer、Redo Log和Undo Logs。
表空间(Tablespaces)
⽤于存储表结构和数据。表空间⼜分为系统表空间、独⽴表空间、通⽤表空间、临时表空间、Undo表空间等多种类型;
系统表空间(The System Tablespace)
包含InnoDB数据字典,Doublewrite Buffer,Change Buffer,Undo Logs的存储区域。系统表空间也
默认包含任何⽤户在系统表空间创建的表数据和索引数据。系统表空间是⼀个共享的表空间因为它是被多个表共享的。该空间的数据⽂件通过参数innodb_data_file_path 控制,默认值是ibdata1:12M:autoextend(⽂件名为ibdata1、12MB、⾃动扩展)。
独⽴表空间(File-Per-Table Tablespaces)
默认开启,独⽴表空间是⼀个单表表空间,该表创建于⾃⼰的数据⽂件中,⽽⾮创建于系统表空间中当innodb_file_per_table选项开启时,表将被创建于表空间中。否则,innodb将被创建于系统表空间中。每个表⽂件表空间由⼀个.ibd数据⽂件代表,该⽂件默认被创建于数据库⽬录中。表空间的表⽂件⽀持动态(dynamic)和压缩(commpressed)⾏格式。
通⽤表空间(General Tablespaces)
通⽤表空间为通过create tablespace语法创建的共享表空间。通⽤表空间可以创建于mysql数据⽬录外的其他表空间,其可以容纳多张表,且其⽀持所有的⾏格式。
CREATE TABLESPACE ts1 ADD DATAFILE ts1.ibd Engine=InnoDB; //创建表空间ts1
CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1; //将表添加到ts1表空间
撤销表空间(Undo Tablespaces)
撤销表空间由⼀个或多个包含Undo⽇志⽂件组成。在MySQL 5.7版本之前Undo占⽤的是System Tablespace共享区,从5.7开始将Undo从System Tablespace分离了出来。InnoDB使⽤的undo表空间由innodb_undo_tablespaces配置选项控制,默认为0。参数值为0表⽰使⽤系统表空间ibdata1;⼤于0表⽰使⽤undo表空间undo_001、undo_002等。
临时表空间(Temporary Tablespaces)
分为session temporary tablespaces 和global temporary tablespace两种。session temporary tablespaces 存储的是⽤户创建的临时表和磁盘内部的临时表。global temporary tablespace储存⽤户临时表的回滚段(rollback segments )。mysql服务器正常关闭或异常终⽌时,临时表空间将被移除,每次启动时会被重新创建。
数据字典(InnoDB Data Dictionary)
InnoDB数据字典由内部系统表组成,这些表包含⽤于查表、索引和表字段等对象的元数据。元数据物理上位于InnoDB系统表空间中。由于历史原因,数据字典元数据在⼀定程度上与InnoDB表元数据⽂件(.frm⽂件)中存储的信息重叠。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论