[玩转MySQL之十一]MySQL InnoDB文件存储结构

一、简介

从物理意义上讲,InnoDB表由共享表空间文件(ibdata1)、独占表空间文件(ibd)、表结构文件(.frm)、以及日志文件(redo文件等)组成。

1.1 表结构文件

在MYSQL中建立任何一张数据表,在其数据目录对应的数据库目录下都有对应表的.frm文件,.frm文件是用来保存每个数据表的元数据(meta)信息,包括表结构的定义等,.frm文件跟数据库存储引擎无关,也就是任何存储引擎的数据表都必须有.frm文件,命名方式为数据表名.frm,如user.frm. .frm文件可以用来在数据库崩溃时恢复表结构。

2.1 表空间结构

数据段(Segment): 即B+树的叶子节点,索引段即为B+树的非叶子节点InnoDB存储引擎的管理是由引擎本身完成的,表空间(Tablespace)是由分散的段(Segment)组成。一个段(Segment)包含多个区(Extent)。

区(Extent): 由64个连续的页(Page)组成,每个页大小为16K,即每个区大小为1MB,创建新表时,先使用32页大小的碎片页存放数据,使用完后才是区的申请(InnoDB最多每次申请4个区,保证数据的顺序性能)

页(Page)类型有:数据页、Undo页、系统页、事务数据页、插入缓冲位图页、以及插入缓冲空闲列表页。

InnoDB引擎有两种管理表空间的方法:
* 共享表空间
* 独立表空间**

2.2 共享表空间

2.2.1 定义

Innodb的所有数据保存在一个单独的表空间里面,而这个表空间可以由很多个文件组成,一个表可以跨多个文件存在,所以其大小限制不再是文件大小的限制,而是其自身的限制。从Innodb的官方文档中可以看到,其表空间的最大限制为64TB,也就是说,Innodb的单表限制基本上也在64TB左右了,当然这个大小是包括这个表的所有索引等其他相关数据。

2.2.2 优点

可以把表空间分成多个文件存放到各个磁盘上(表空间文件大小不受表大小的限制,如一个表可以分布在不同步的文件上)。数据和文件放在一起方便管理。

2.2.3 缺点

所有的数据和索引存放到一个文件中将会是一个很大的文件,虽然可以把一个大文件分成多个小文件,但是多个表及索引在表空间中混合存储,这样对于一个表做了大量删除操作后表空间中将会有大量的空隙,特别是对于统计分析,日值系统这类应用最不适合用共享表空间。

共享表空间管理会出现表空间分配后不能回缩的问题,当出现临时建索引或是创建一个临时表的操作表空间扩大后,就是删除相关的表也没办法回缩那部分空间了。当存在磁盘监控时,也许就会报警不断了,但实际上MySQL还可以运行良好。另外,当磁盘上占用较多时性能也不是太好。

这种情况处理只能是是建一个新的Slave从主库上Dump出来,然后在Dump到从库中,动作较大。

对于InnoDB Hot Backup备份的操作(或是直接冷备),每次需要CP的文件比较大。如果现在有180G的表空间,但实际数据只有50多G,那么我们将面对每次需要拷180G的数据。

这种方式也许mysqldump是一个好的处理方式了。

2.3 独立表空间

2.3.1 定义

每一个表都将会生成以独立的文件方式来进行存储,每一个表都有一个.frm表描述文件,还有一个.ibd文件. 其中这个文件包括了单独一个表的数据内容以及索引内容,默认情况下它的存储位置也是在表的位置之中。

这个时候的单表限制,又变成文件系统的大小限制了。

在配置文件(my.cnf)中设置: innodb_file_per_table 即可设置为独立表空间

2.3.2 优点

  1. 每个表都有自已独立的表空间。
  2. 每个表的数据和索引都会存在自已的表空间中。
  3. 可以实现单表在不同的数据库中移动。
  4. 空间可以回收(除drop table操作处,表空不能自已回收)
    • Drop table操作自动回收表空间,如果对于统计分析或是日值表,删除大量数据后可以通过:alter table TableName engine=innodb;回缩不用的空间。
    • 对于使用独立表空间的表,不管怎么删除,表空间的碎片不会太严重的影响性能,而且还有机会处理。
    • 对于使innodb-plugin的Innodb使用turncate table也会使空间收缩。

2.3.3 缺点

单表增加过大,当单表占用空间过大时,存储空间不足,只能从操作系统层面思考解决方法;

对于单表增长过大的问题,如果使用共享表空间可以把文件分开,但有同样有一个问题,如果访问的范围过大同样会访问多个文件,一样会比较慢。对于独立表空间也有一个解决办法是:使用分区表,也可以把那个大的表空间移动到别的空间上然后做一个连接。其实从性能上出发,当一个表超过100个G有可能响应也是较慢了,对于独立表空间还容易发现问题早做处理。

2.4 表空间推荐

推荐使用独立表空间。在性能和运维上独立表空间比共享的表空间有很多优势。

  • 可以更好从系统上监控数据的大小,每个表的大小。
  • nnoDB Hot Backup(冷备)的表空间cp不会面对很多无用的copy了。而且利用innodb hot backup及表空间的管理命令可以实现单现移动。
  • 从性能上对比共享表空间和独立表空间:
    • 共享表空间在Insert操作上少有优势。其它都没独立表空间表现好。这里也有一个TIPS当启用独立表空间时,请合理调整一下:innodb_open_files 。
    • 从Linux系统处理上出发:文件系统fsync一大片更新数据,对系统io冲击较大。若分隔成多个小数据fsync,能够减少对读的影响。 同时从mysql代码,发现mysql保证两次fsync之间至少有20ms的sleep,这样的话,若将一次fsync变成多次小数据操作,应该能够减少慢查询的比例。所以对于大量更新操作的系统不太适合用共享表空间。

二、文件存储

下面的文件存储主要讲解独立表空间的存储结构,详情如下:

2.1 共享表空间

可以由参数innodb_data_file_path制定,默认存放在数据存放根目录下

2.2 日志组文件

在MySQL的数据目录下存在日志组文件: ib_logfile0、ib_logfile1….,默认均为5M

2.3 表结构文件:*.frm

在MYSQL中建立任何一张数据表,在其数据存放目录对应的数据库目录下都有对应表的.frm文件,

.frm文件是用来保存每个数据表的元数据(meta)信息,包括表结构的定义等,

在MySQL中,“.frm”文件跟数据库存储引擎无关,任何存储引擎的数据表结构文件都存储为.frm文件,

命名方式为“tablename.frm”,如user.frm,.frm文件可以用来在数据库崩溃时恢复表结构。

2.4 独占表空间文件:*.ibd

在innodb_file_per_table配置为ON时设置为独占表空间,此时,系统将为每一个表单独存储为“.ibd”文件,

(如user.ibd)在此文件中,存储与该表相关的数据、索引、表的内部数据字典信息。

2.5 字符集和排序规则文件:db.opt

文件中记录了该库的默认字符集编码和字符集排序规则。如果你创建数据库指定默认字符集和排序规则,

后续创建的表如果没有指定字符集和排序规则,那么该新建的表将采用db.opt文件中指定的属性。

如果删除这个db.opt,MySQL在建表时将参照全局的字符设置,即default-character-set ,

这个影响是在建表的时候才会有体现,你不在那个库新建表,是没什么差异的。

[root@ecs-prod-my57-fsolap-ro base]# cat db.opt
default-character-set=utf8
default-collation=utf8_general_ci

2.6 binlog二进制日志文件

记录主数据库服务器的DDL和DML操作。

在主从复制时,二进制日志文件将通过Binlog Dump线程传递给从服务器的I/O线程,

I/O线程获取事件数据后传递给从服务器的relaylog,然后在从服务器重做一遍实行复制。

可以通过参数:log-bin来设置二进制的存储目录和文件名

2.7 二进制日志索引文件 xxx-bin.index

在数据库目录下有一个索引文件用来记录已经使用的二进制日志文件的名字,该索引文件的名字为”xxx-bin.index”。

索引文件记录二进制文件的具体存储位置以及文件名,最后一行表示当前正在使用的二进制日志名字

其存储目录和log-bin设置的目录一致

2.8 从库记录同步信息文件

如果MySQL作为从库,其记录主库同步信息的文件主要有master.info,relay-bin.info。其存储目录在MySQL数据目录中。

master.info存储主库信息及从库当前读取到的binglog位置

[root@ecs-prod-my57-fserp-ro data]# cat master.info
25
mysql-bin.001643   <----- 主服务器binlog dump线程传递的给从服务器binlog文件
388212789  <-- 主服务器Position
192.168.11.22  <-- 主服务地址
xxxxxxx  <-- 提供复制的账户
xxxxxxxxxx <-- 提供复制的账户密码
3306  <-- 主服务地址端口
10

relay-log.info存储从库执行到主库binlog的信息

/data/mysql/mysql3306/logs/relaylog/my_3306-relay-bin.003184   <--从服务器I/O线程更新event的从服务器relay-log文件
378393216 <--从服务器Relay_Log_Pos
mysql-bin.001643  <--从服务器I/O线程传递的主服务器binlog文件
378393283 <-- 主服务器Position
0
0
1

2.9 从库存储主库二进制文件

在从库数据库目录下存储这从库I/O县城获取事件数据后并进行记录主库二进制内容的文件,其中索引文件为xxx-relay-log.index.

xxx-relay-log.index文件记录着当前执行过或者正在执行的二进制文件,最后一行币哦事当前正在使用的二进制文件。如:

[root@ecs-prod-my57-fserp-ro relaylog]# cat my_3306-relay-bin.index
/data/mysql/mysql3306/logs/relaylog/my_3306-relay-bin.003183
/data/mysql/mysql3306/logs/relaylog/my_3306-relay-bin.003184

三、参考文献

MySQL InnoDB 共享表空间和独立表空间
Innodb共享表空间VS独立表空间
MySQL InnoDB的存储结构总结
MySQL中文件存储形式

本文来自网络,不代表云小秘立场,转载请注明出处:https://www.cloudmmu.com/680.html

作者: 欧邦

折腾不休,奋斗不止

发表评论

联系我们

联系我们

15877997995

在线咨询: QQ交谈

邮箱: oubang@live.cn

工作时间:周一至周五,9:00-21:00,节假日休息
关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部