????作者简介:小明java问道之路,专注于研究 Java/ Liunx内核/ C++及汇编/计算机底层原理/源码,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。
???? 热衷分享,喜欢原创~ 关注我会给你带来一些不一样的认知和成长。
???? CSDN博客专家/后端领域优质创作者/内容合伙人、InfoQ签约作者、阿里云专家/签约博主、51CTO专家 ????
????如果此文还不错的话,还请????关注、点赞、收藏三连支持????一下博主~
专栏系列(点击解锁)
学习路线(点击解锁)
知识定位
????MySQL从入门到精通????
????计算机底层原理????
????数据结构与企业题库精讲????
????互联网架构分析与实战????
本文目录
1、系统表空间(The System Tablespace)
2、独立表空间(File-Per-Table Tablespaces)
5、临时表空间(Temporary Tablespaces)
三、表结构文件(数据字典 InnoDB Data Dictionary)
本文导读
在 InnoDB 存储引擎中,存储结构分为逻辑结构和物理结构,本文详细讲解Innodb的物理结构,包括表空间(独立表空间、共享表空间)、日志文件组(重做文件组)和表结构定义文件组成,及其细节。
同时本文也是对前面文章的一个补充,结合使用效果更佳:《高性能高可用设计实战-索引篇》、《MVCC详解与MVCC实现原理》、《MySQL日志系统以及InnoDB背后的技术》、《Innodb存储引擎逻辑存储结构与底层实现解析》。
一、Innodb物理存储结构
从物理上讲,InnoDB由表空间(独立表空间、共享表空间)、日志文件组(重做文件组)和表结构定义文件组成。在物理可以认为就是InnoDB磁盘。
InnoDB磁盘由五部分组成:表空间(Tablespaces)、InnoDB数据字典(InnoDB Data Dictionary)、Doublewrite缓冲区(Doublewrite Buffer)、重做日志(Redo Log)和撤消日志(Undo Log)。
二、表空间(Tablespaces)
Innodb 存储引擎其数据根据表空间进行管理。
表空间用于存储表结构和数据。表空间可分为系统表空间、独立表空间、通用表空间、临时表空间、撤消表空间和其他类型。
1、系统表空间(The System Tablespace)
系统表空间,包含InnoDB数据字典、Doublewrite Buffers、Change Buffers和Undo Logs的存储区域。
默认情况下,系统表空间还包含任何用户在系统表空间中创建的表数据和索引数据。系统表空间是一个共享表空间,因为它由多个表共享。系统表空间可以有一个或多个数据文件。默认情况下,将在数据目录中创建ibdata1文件,默认大小为12M 。
-- 通过 innodb_data_file_path 配置文件的大小和数量。
-- innodb_data_file_path 用来指定innodb tablespace文件
-- 如果我们不在My.cnf文件中指定innodb_data_home_dir和innodb_data_file_path
-- 那么默认会在datadir目录下创建ibdata1 作为innodb tablespace。
-- 默认值:
-- 文件名为ibdata1,autoextend自动扩展
innodb_data_file_path = ibdata1:12M:autoextend
2、独立表空间(File-Per-Table Tablespaces)
独占表空间文件存储在 /data/database1/table1.ibd 文件中,其中仅存储表的相应数据和索引,其余的撤消日志(undo log)、更改缓冲区(change buffer)和双写缓冲区(doublewrite buffer)仍存储在系统表空间中。
如果希望每个表都有一个单独的表空间文件,可以使用innodb_file_per_table。默认情况下从MySQL 5.6开始,启用的(独立的表空间是单个表空间,表是在其自己的数据文件中创建的,而不是在系统表空间中创建的)。如果禁用配置,则将在系统表空间中创建表。
-- 开启独立表空间参数为:innodb_file_per_table
-- 独立表空间:tablename.ibd
-- 新建表被创建于【表空间】中,每一个表建立ibd的扩展文件
-- 文件名为:表名.ibd,该文件默认被创建于数据库目录中,表空间的表文件支持动态和压缩行格式。
innodb_file_per_table = ON
-- 系统表空间:ibdataX,innodb将被创建于【系统表空间】中,即ibdataX中
-- X代表从1开始的一个数字
innodb_file_per_table = OFF
-- 查看表的存储表空间的存储方式值
show variables like 'innodb_file_per_table';
-- 修改存储表空间的存储方式值为OFF
set global innodb_file_per_table=off;
独立表空间和系统表空间的优缺点:
优点: 1、重建或删除表后,独占表空间的磁盘空间可以被回收,而系统表空间优化的磁盘空间只能被后续数据表重用,不能被操作系统回收。2、每个表之间的文件隔离使表文件维度的备份、恢复和压缩更加灵活,而不会影响其他表。
缺点:1、fsync系统调用不友好。如果使用表空间文件,一次系统调用可以完成数据存储,但如果将表空间文件拆分为多个文件。原始的fsync可以对所有涉及的表空间文件执行一次,从而增加fsyncs的数量。2、多个文件将占用更多空间和文件描述符。如果管理不当,很容易浪费空间。例如删除后,系统表空间中的所有表都可以重用标记的空间。如果它是独占表,则只能由同一个表重用。
3、通用表空间(General Tablespaces)
公共表空间是通过 create tablespace 创建表空间语法创建的共享表空间,可以在mysql数据目录之外的其他表空间中创建公共表空间,其作用是可以保存多个表并支持所有行格式。
系统表空间中的所有表共享一个文件,独立表空间中每个表都有一个文件。
优点和缺点都很明显。公共表空间是系统表空间和独立表空间之间的折衷方案。您可以选择指定一些表并将它们存储在公共表空间中。
-- 在/data 目录下创建表空间
CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB;
-- 在指定目录创建表空间
CREATE TABLESPACE `ts1` ADD DATAFILE '/my/tablespace/directory/ts1.ibd' Engine=InnoDB;
-- 将表添加到通用表空间
CREATE TABLE sub_order_info (c1 INT PRIMARY KEY) TABLESPACE ts1;
4、撤销表空间(Undo Tablespaces)
撤消表空间(Undo Tablespaces)由一个或多个撤消日志文件组成。在MySQL 5.7之前,Undo占用了系统表空间(System Tablespace)共享。从5.7开始,Undo与系统表空间分离。
默认情况下,undo日志存储在系统表空间中,可以配置为存储在一个或多个重做表空间文件,配置 innodb_undo_directory 的 undo 表空间文件的位置。默认值为/data/undo001,
innodb_undo_tablespaces=0:默认值,表示系统表空间ibdata1的使用;大于0表示使用undo表空间undo_001、undo_002等,如果使用的是 SSD 存储,推荐配置 undo 表空间。
5、临时表空间(Temporary Tablespaces)
当MySQL服务器正常关闭或异常终止时,临时表空间将在每次启动时删除并重新创建。
默认情况下,临时表空间数据文件将自动展开,并根据需要自动展开。删除临时表后,可以重用释放的空间,但文件大小保持不变。ibtmp1将在数据库重新启动后重新初始化。您还可以配置以指定最大文件大小。
innodb_temp_data_file_path=ibtmp1:12M:autoextend:max:500M
有两种类型的临时表空间:会话临时表空间(session temporary tablespaces),存储用户创建的临时表和磁盘内的临时表;全局临时表空间(global temporary tablespace)存储用户临时表的回滚段(rollback segments)。
三、表结构文件(数据字典 InnoDB Data Dictionary)
InnoDB数据字典由内部系统表组成,记录了所有表、索引的元数据,由于历史原因这里数据字典元数据,和表的元数据 .frm 文件存在信息重叠。
这些表包含查找表、索引和表字段等对象的元数据。元数据物理上位于InnoDB系统表空间中。
四、双写缓冲区(Doublewrite Buffer)
双写缓冲区(Doublewrite Buffer),位于系统表空间中,是一个存储区域。在将BufferPage页刷新到磁盘上的实际位置之前,数据将存储在Doublewrite缓冲区中。
如果操作系统、存储子系统或mysqld进程在页面写入期间崩溃,InnoDB可以在崩溃恢复期间从Doublewrite缓冲区找到页面备份。在大多数情况下,默认情况下启用双写缓冲区。
-- 禁用Doublewrite 缓冲区
innodb_doublewrite = 0
-- 数据文件写入操作会通知操作系统不要缓存数据,也不要用预读
-- innodb_flush_method控制innodb数据文件及redo log的打开刷写模式
innodb_flush_method = O_DIRECT
五、日志文件(Log)
1、重做日志(Redo Log)
重做日志是一种基于磁盘的数据结构,用于在崩溃恢复期间纠正由不完整事务写入的数据。
MySQL以循环方式写入重做日志文件,将所有更改记录到InnoDB中的缓冲池中。
当发生实例故障且数据无法更新到数据文件时,在重新启动数据库以再次将数据更新到数据时,必须重做数据库。在执行读/写事务期间,会不断生成重做日志。默认情况下,磁盘上的重做日志由两个名为ib_ Logfile0和ib_ logfile1文件的物理表示形式的文件组成。
2、撤销日志(Undo Logs)
Undo 日志是在事务开始之前保存的修改数据的备份。它用于回滚事务。Undo 日志属于逻辑日志,根据每行记录进行记录。Undo 日志存在于系统表空间、撤消表空间和临时表空间中。
3、错误日志(error log)
错误日志(Error Log)是MySQL中最常用的日志。它主要记录MySQL服务器启动和关闭过程中的信息,以及服务器运行过程中的故障和异常。
在MySQL中,默认情况下启用错误日志功能。通常,错误日志存储在MySQL数据库的数据文件夹中,通常命名为hostname err其中,hostname表示MySQL服务器的主机名。
在MySQL配置文件中,可以通过日志错误和日志警告来定义错误日志中记录的信息。日志错误定义是否启用错误日志功能和错误日志的存储位置,日志警告定义是否在错误日志中记录警告信息。
4、二进制日志(bin log)
二进制日志(Binary Log)也可以称为更新日志(Update Log)。它是MySQL中非常重要的日志。它主要用于记录数据库中的更改,即SQL语句的DDL和DML语句,不包括数据记录查询操作。
如果MySQL数据库意外停止,您可以通过二进制日志文件查看用户执行了哪些操作以及对数据库服务器文件进行了哪些修改,然后根据二进制日志文件中的记录恢复数据库服务器。默认情况下,
二进制日志记录处于关闭状态。
5、慢查询日志(Slow Query Log)
慢速查询日志用于记录在MySQL中执行超过指定时间的查询语句。通过缓慢的查询日志,您可以发现哪些查询语句对于优化效率低下。
一般来说,MySQL慢速查询日志是排除SQL语句故障和检查当前MySQL性能的重要功能。如果不需要调整,通常不建议启用此参数,因为启用慢速查询日志或多或少会影响性能。
默认情况下,慢速查询日志功能处于关闭状态。
6、全量日志(general log)
默认情况下,MySQL不会打开 general log,该日志将记录MySQL的所有SQL语句,无论是查询语句、DML语句、DDL语句还是DCL语句。所有这些语句都将记录在 general log 日志文件中。甚至连接和断开MySQL数据库的语句。
MySQL将按照收到的顺序在常规日志中记录它收到的所有SQL语句。我们应该注意,此处接受的SQL语句的顺序并不意味着SQL语句按此顺序执行。有时,某些SQL语句可能只有在释放其他锁后才能执行。SQL语句的执行顺序与binlog中的顺序匹配。
7、中继日志(relay log)
中继日志的内容应用于从属服务器,以便从属服务器和主服务器的数据一致。中继日志在许多方面与二进制日志相似。不同的是,从I/O线程读取主服务器的二进制日志并将其记录到从服务器的本地文件中,然后SQL线程读取中继日志并将它应用到从服务器,从而使从服务器和主服务器的数据一致。
总结
在 InnoDB 存储引擎中,存储结构分为逻辑结构和物理结构,本文详细讲解Innodb的物理结构,包括表空间(独立表空间、共享表空间)、日志文件组(重做文件组)和表结构定义文件组成,及其细节。
同时本文也是对前面文章的一个补充,结合使用效果更佳:《高性能高可用设计实战-索引篇》、《MVCC详解与MVCC实现原理》、《MySQL日志系统以及InnoDB背后的技术》、《Innodb存储引擎逻辑存储结构与底层实现解析》。