InnoDB磁盘结构
表空间
表空间(tablespaces)用于存储表结构和数据(含索引),表空间又分为系统表空间、独立表空间、通用表空间、临时表空间、Undo表空间等多种类型
共享表空间
共享表空间可以被多个表共享,包括系统表空间和通用表空间
系统表空间
系统表空间是change buffer在磁盘上的存储区域
在5.7之前的版本中,系统表空间还包括双写缓冲区,此存储区域在8版本中在独立的双写文件中
系统表空间可以包含一个或多个数据文件。默认情况下,在数据目录中创建一个名为ibdata1
的系统表空间数据文件
系统表空间数据文件的大小和数量由
innodb_data_file_path
启动选项定义默认值:ibdata1:12M:autoextend
- ibdata1:文件名
- 12M:文件大小
- autoextend:自动扩展,默认每次扩展64m
通用表空间
默认情况下在使用innodb创建的表使用的是独立表空间,但是可以显示的指定到通用表空间
功能
-
与系统表空间类似,通用表空间是能够为多个表存储数据的表空间
-
与独立表空间相比,通用表空间具有潜在的内存优势
服务器在表空间的生命周期内将元数据保存在内存中。与独立表空间中单独文件的数量的表相比,较少的通用表空间中的多个表对表空间元数据消耗的内存更少
-
通用表空间数据文件可以独立于MySQL数据目录
-
通用表空间支持所有表行格式和相关功能
语法
- 创建通用表空间:
create tablespace xxx add datafile 'xxx.ibd'
- 删除通用表空间:
drop tablespace xxx
- 指定使用通用表空间:
create table ... tablespace xxx
- 撤销指定的通用表空间,并换成独立表空间:
alter table xxx tablespace innodb_file_per_table
(也可以换成指定的其他通用表空间)
独立表空间
独立表空间包含单个innodb表的数据和索引,并存储在文件系统中的单个数据文件中
在数据目录中名为.ibd
撤销表空间
撤销表空间用来存储undo日志,由多个包含undo日志文件组成
5.7之前undo在系统表空间中
在8.0.23之前对于数据页为16k(默认),默认的撤销表空间的大小是10m,在之后的版本中初始大小是16m。扩展采用翻倍的方式
撤销表空间的文件名默认为undo_001
根据数量序号递增。默认2个,最多支持127个
临时表空间
临时表概念:
- 外部临时表:通过create temporary table创建的表就是临时表,会话结束,就自动清理,show tables不显示临时表信息
- 内部临时表:执行复杂查询时,执行计划中包含了Using Temporary,比如分组、排序、去重等。mysql内部会自动生产临时表
临时表空间包括会话临时表空间和全局临时表空间
会话临时表空间
会话临时表空间存储:用户创建的临时表和优化器创建的临时表
服务器启动时,会创建一个由10个临时表空间(磁盘文件)组成的一个池(文件后缀为.ibt),当会话断开连接时,其占用的临时表空间会被释放回池中。池的大小永远不会缩小,如果不够用会自动扩容
临时表空间池在正常关机时会被删除
全局临时表空间
全局临时表空间(ibtmp1)存储对用户创建的临时表进行更改的回滚段
双写缓冲区
双写缓冲区是一个存储区域,为了解决写失效问题,innodb实现了双写缓冲区。在刷盘到真正的位置前,会将数据存在双写缓冲区。这样服务器重启时,如果出现数据页损坏,可以在redolog之前,通过双写缓冲区的副本还原该页
在MySQL8.0.20之前,双写缓冲区位于系统表空间中,从8.0.20之后,双写缓冲区位于双写文件中
写失效
innodb的页(16k)和操作系统的页(4k)大小不一致,innodb页写入到磁盘时,要分成4次写。如果写入页的时候宕机了,可能会出现只写了一部分的情况,这种情况就叫写失效
Redo Log File
WAL(writer ahead logging)写前日志,是一种数据安全写入机制。就是先写日志,然后再写入磁盘,这样既能保证数据的安全性,MySQL种的redo log就是采用的wal机制
innodb对数据的更新,是先将更新写入到redo log,然后会再系统空闲的时候或者按照指定策略更新到磁盘。这就是所谓的wal
redo log(重做日志)包括两部分:一个是内存中的日志缓冲redo log buffer
,另一个是磁盘上的日志文件redo log file
。默认情况下,重做日志在磁盘上由两个名为ib_logfile0
和ib_logfile1
的文件展示
Undo Log File
undo log(撤销日志)是一种撤销回退的日志,在数据库事务开始之前,MySQL会先记录更新前的数据到undo log中,当事务回滚时,可以利用undo log进行回退
undo log的生产和销毁:undo log在事务开始前产生;事务提交时,并不会立即删除undo log,innodb会将该事务对应的undolog 放入到删除列表中,后面会通过后台线程purge进行回收处理
注意:undo log也会产生redo log,因为undo log也要实现持久化保护