MySQL指南(二)物理文件层的实现
- 2020 年 1 月 16 日
- 筆記
在上一章我们了解到,物理文件层在MySQL架构位于最底层,将数据库的数据存储在文件系统上,并完成与存储引擎的交互。存储数据包括日志文件,数据文件,配置文件等。本章将介绍linux环境下MySQL的各类文件。

配置文件
启动一个数据库实例时,MySQL数据库会去读取配置文件,根据配置文件的参数来启动数据库实例。如果没有配置文件,MySQL会按照编译时的默认参数设置实例。执行以下命令可以查看,当MySQL数据库实例启动时,它会从哪些位置查找配置文件。
./bin/mysql --help | grep my.cnf

可以看到,MySQL是按照 /etc/my.cnf—>/etc/mysql/my.cnf—>/usr/etc/my.cnf—> ~/.my.cnf
的顺序依次读取配置文件的,如果不同文件中同一参数有冲突,将会以最后一个读取的为准。Linux环境下,配置文件一般放在/etc/my.cnf
下;Windows环境下,配置文件的后缀名可以是.cnf,也可能是 .ini。
运行cat /etc/my.cnf
命令,来看配置文件中具体有哪些内容。可以见到文件中分了不同的组,每组保存不同用途的参数信息。

[mysqld]组
指定mysql服务器启动时,读取的初始化参数信息。
datadir指定了MySQL的数据目录,即数据文件存放的路径。
socket指定socket文件路径。socket文件是Unix/Linux环境下独有的一个文件,当MySQL客户端和数据库实例在同一台服务器上时,可以使用此文件用Unix套接字的形式来连接实例,命令如下:
mysql -uroot -S /var/lib/mysql/mysql.sock

[mysqld_safe]组
mysqld_safe是在Unix上启动mysqld服务器的推荐方法,增加了一些安全特性,例如在发生错误时重新启动服务器,并将运行时信息记录到错误日志等。这里指定mysqld_safe服务启动时的初始化参数。
log-error指定错误日志的保存路径;
pid-file指定pid文件的保存路径。pid文件是mysqld应用程序在Unix/Linux环境下的一个进程文件,和许多其他Unix/Linux服务端程序一样,它存放着自己的进程ID。
[client]组
指定mysql客户端连接mysql服务器时,读取的初始化参数信息。
数据文件
数据文件包括MySQL在运行过程中产生的所有数据,数据保存的目录称为数据目录。在配置文件my.conf中可以获取到这个路径,同样也可以登录MySQL查看datadir系统变量的值来获取该路径。
show variables like 'datadir';

数据目录具体存放了哪些内容?首先来看一个建库语句。当我们启动MySQL实例,使用CREATE DATABASE <数据库名>语句创建一个新的数据库,MySQL会在数据目录下创建一个和数据库名同名的子目录(文件夹),并在这个子目录下创建一个名为db.opt的文件,包含了新建库的各种配置属性。也就是说,每个数据库都对应数据目录下的一个子目录。

现在查看一下我在本地建立了哪些数据库。其中demo和scarlett都是自建库,其他三个为MySQL自建库。再来看对应数据目录的内容。除了information_schema这个特殊的系统数据库外,其他数据库都拥有自己的子目录。

再来看新建表时文件系统层面的变化。每个表实质包含2部分内容:表结构的定义,和表数据。表结构定义指标的名称,列数,数据类型等结构信息,用.frm文件存储。
表数据指的就是我们存入的一行行的数据,每个存储引擎有不同的表数据保存方式。MyISAM的数据和索引在文件层面是分开存放的,都存放到对应的数据库子目录下。新建一个表myisam_table,使用MyISAM存储引擎,打开其所在数据库对应的目录下面,会发现有如下三个文件:
myisam_table.frm //表结构文件 myisam_table.MYD //数据文件 myisam_table.MYI //索引文件

InnoDB的数据和索引是存放在一起的,此外,InnoDB还有两种表空间方式:独立表空间和系统表空间。
系统表空间,对应文件系统上一个或多个真实文件。默认情况下,InnoDB会在数据目录下创建一个名为ibdata1的文件,对应系统表空间。且这个文件为自扩展文件,不够用的时候能自己增加大小。所有表共享这些ibdata文件。
在MySQL5.6.6及之后的版本里,InnoDB开始为每个表建立一个独立表空间,单独存放表数据。独立表空间用.ibd文件表示,每个表对应一个.ibd文件,存放在所属数据库目录下。
新建一个表innodb_table,使用InnoDB存储引擎,打开其所在数据库对应的目录下面,会发现有如下文件:
innodb_table.frm //表结构文件 innodb_table.ibd //数据文件

同时,数据目录下面的ibdata1文件,即为InnoDB的系统表空间。

总结一下,MySQL的文件结构描述如下。

auto.cnf
保存MySQL实例server-uuid的值。
mysql.sock
MySQL socket套接字文件,当MySQL客户端和数据库实例在同一台服务器上时,可以使用此文件用Unix套接字的形式来连接实例。
.frm文件
存储与表相关的元数据(meta)信息都存放在此文件中,包括表结构的定义信息等。
不管什么存储引擎,每一个表都会有一个以表名命名的.frm文件。
.MYD文件和.MYI文件
MyISAM引擎的索引与数据是分开存储的。.MYD文件存放MyISAM表的数据,.MYI文件存放MyISAM表的索引相关信息。且对于MyISAM表,MySQL只缓存其索引文件,数据文件的缓存由操作系统本身完成。一个MyISAM表对应一个.MYD文件和一个.MYI文件,它们都存放在所属数据库目录下。
.ibd文件和ibdata文件
存放innoDB的数据文件(包括索引)。
innoDB存储引擎有两种表空间方式:独享表空间和共享表空间。
独享表空间使用.ibd文件来存放数据,且每个表一个.ibd文件,文件存放在所属数据库目录下;
共享表空间使用.ibdata文件,所有表共同使用一个(或多个,自行配置)ibdata文件。
db.opt文件
此文件在每一个自建的库里都会有,记录这个库的默认使用的字符集和校验规则。
日志文件
MySQL包含许多日志文件,用来记录信息,保证服务。常用的有以下五种文件。
1. 错误日志(Error Log),记录mysql服务的启停时正确和错误的信息,还记录启动、停止、运行过程中的错误信息。默认保存路径为/var/log/mysqld.log.

2. 二进制日志(Binary Log),二进制格式的文件,记录所有更改数据的语句,用于数据库的主从复制及数据的增量恢复;
3. 查询日志(General query Log),记录所有连接和执行的语句;
4. 慢查询日志(Slow Log),记录所有的慢查询语句(超过指定时间的 SQL 语句查询语句),用于分析优化SQL;
5. 中继日志(Relay Log),主从复制时使用的日志。
关于二进制日志和中继日志的详细介绍,可阅读文章https://cloud.tencent.com/developer/article/1541850