MySQL作为常用的关系型数据库,其数据的存储位置和底层存储结构是数据库运维和性能优化的重要基础,不同存储引擎的存储逻辑存在明显差异,其中InnoDB是目前最常用的存储引擎,下面我们围绕这两方面展开说明。

MySQL数据的默认存储位置
MySQL的数据存储目录由配置文件中的datadir参数指定,不同系统的默认路径有所不同:
- Linux系统默认路径通常为
/var/lib/mysql/ - Windows系统默认路径通常为
C:ProgramDataMySQLMySQL Server 8.0Data
我们可以通过SQL语句直接查询当前实例的datadir值:
-- 查询MySQL数据存储目录 SHOW VARIABLES LIKE 'datadir';
执行后会返回类似如下的结果,其中Value字段就是当前的数据存储路径:
| Variable_name | Value |
|---|---|
| datadir | /var/lib/mysql/ |
在datadir目录下,每个数据库会对应一个同名的文件夹,文件夹中存放该数据库下所有表的相关存储文件,具体文件类型和存储引擎有关。
常见存储引擎的存储结构
InnoDB存储引擎存储结构
InnoDB是MySQL默认的存储引擎,它的存储结构从逻辑上可以分为表空间、段、区、页、行五个层级。
1. 表空间
表空间是InnoDB存储结构的最外层逻辑单位,分为系统表空间和独立表空间:
- 系统表空间:对应
datadir目录下的ibdata1文件,默认存储所有表的数据和索引,以及回滚日志、双写缓冲区等系统信息,默认大小是12MB,可自动扩展。 - 独立表空间:如果开启了
innodb_file_per_table参数(默认开启),每个InnoDB表会对应一个表名.ibd文件,存储该表的数据和索引,系统表空间则只存储少量系统信息。
我们可以通过以下语句查看innodb_file_per_table的状态:
-- 查看独立表空间是否开启 SHOW VARIABLES LIKE 'innodb_file_per_table';
2. 段
表空间由多个段组成,常见的段包括数据段、索引段、回滚段:
- 数据段:存储B+树叶子节点的数据页
- 索引段:存储B+树非叶子节点的索引页
- 回滚段:存储事务回滚用的undo日志
3. 区
区是InnoDB分配存储空间的基本单位,每个区的大小固定为1MB,由64个连续的页组成。即使表的数据量很小,InnoDB也会先分配一个区来保证数据的连续性,减少磁盘随机IO。
4. 页
页是InnoDB和磁盘交互的最小单位,默认大小为16KB,常见的页类型包括数据页、undo页、系统页等。每个数据页中存储的是多行表数据,页的结构包含文件头、页头、最小最大记录、用户记录、空闲空间、页目录、文件尾等部分。
5. 行
行是最终存储用户数据的单位,InnoDB支持两种行格式:Compact和Dynamic(MySQL 8.0默认)。行格式中除了存储用户定义的列数据,还会存储事务ID、回滚指针、隐藏的主键列等额外信息。
我们可以通过以下语句查看某张表的行格式:
-- 查看表的行格式,table_name替换为实际表名 SHOW TABLE STATUS LIKE 'table_name';
MyISAM存储引擎存储结构
MyISAM是MySQL早期的默认存储引擎,它的存储结构和InnoDB有明显区别:
- 每个MyISAM表对应三个文件,都存放在对应数据库的目录下:
表名.frm:存储表的结构定义表名.MYD:存储表的数据(MYData)表名.MYI:存储表的索引(MYIndex)
- MyISAM的索引是非聚簇索引,索引和数据分开存储,B+树的叶子节点存储的是数据行的物理地址,而不是完整的数据。
- MyISAM不支持事务,没有事务相关的日志和回滚段结构。
不同存储引擎存储结构对比
| 对比项 | InnoDB | MyISAM |
|---|---|---|
| 数据索引存储 | 聚簇索引,数据和索引存在同一个ibd文件 | 非聚簇索引,数据和索引分开存储 |
| 事务支持 | 支持事务,有undo、redo日志 | 不支持事务 |
| 锁粒度 | 行级锁 | 表级锁 |
| 外键支持 | 支持外键 | 不支持外键 |
总结
MySQL的数据存储位置由datadir参数控制,我们可以通过SQL语句直接查询具体路径。存储结构方面,InnoDB采用表空间、段、区、页、行的层级结构,支持事务和行级锁,是目前的主流选择;MyISAM的存储结构更简单,但是不支持事务,适合读多写少的场景。了解这些存储逻辑,有助于我们更好地进行数据库的容量规划、性能优化和故障排查工作。