剑指MySQL:架构、调优与运维
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.2 数据库和文件系统的关系

一般我们通过数据库客户端来操作数据,对数据存储的具体位置没有特别留意。MySQL中的数据一旦持久化,就会被存储在磁盘中,服务器重启以后,数据依然存在。操作系统用来管理磁盘的结构被称为文件系统。当我们读取数据的时候,MySQL会从文件系统中把数据读出来返回给我们;当我们写入数据的时候,MySQL会把这些数据写回文件系统中。

2.2.1 查看系统数据库

使用如下语句查看当前MySQL服务器中有哪些数据库。

从结果中可以看到,当前MySQL服务器中共有5个数据库,其中,chapter1是我们在第1章中自定义的数据库,另外4个是MySQL自带的系统数据库,分别是information_schema、mysql、performance_schema和sys。下面讲解这4个系统数据库的作用。

(1)information_schema。information_schema数据库主要用于存储数据库元数据,如数据库名、表名、列的数据类型、访问权限、触发器等。这些信息并不是真实的用户数据,而是一些描述性信息。

(2)mysql。mysql数据库主要用于存储数据库的用户、权限设置、存储过程、帮助信息、时区信息等。

(3)performance_schema。performance_schema数据库主要用于收集数据库服务器性能参数,可以用来监控MySQL服务的各类性能指标,如提供进程等待的详细信息,包括锁、互斥变量、文件信息、内存使用情况等。

(4)sys。sys是从MySQL 5.7开始新增的系统数据库。该数据库通过视图的形式把information_schema和performance_schema数据库结合起来,帮助系统管理员和开发人员监控MySQL的技术性能。

2.2.2 数据库在文件系统中的表示

在使用CREATE DATABASE语句创建一个数据库的时候,MySQL会帮我们做两件事。

(1)在数据目录下创建一个和数据库名同名的子目录。

(2)在与该数据库名同名的子目录下创建一个名为db.opt的文件(仅限MySQL 5.7及以前的版本),这个文件中包含该数据库的各种属性,如该数据库的字符集和校对规则。

使用如下语句查看MySQL数据目录下的内容。从结果中可以看到,这个数据目录下的文件和子目录比较多,除了information_schema这个系统数据库,其他数据库在数据目录下都有对应的文件和子目录,包括我们在第1章中自定义的数据库chapter1。注意,information_schema是唯一一个在数据目录下没有对应文件和子目录的系统数据库。

2.2.3 表在文件系统中的表示

每张表的信息可以分为表结构的定义信息和表中的数据信息。其中,表结构的定义信息包含该表的名称、表中有多少列、每列的数据类型、约束条件和索引、使用的字符集和校对规则等信息,这些信息都体现在创建表的语句中。

在MySQL中,存储引擎主要负责数据的读取和写入。下面分别介绍InnoDB和MyISAM存储引擎下表在文件系统中的表示。

1.InnoDB存储引擎下表在文件系统中的表示

在MySQL 8.0以前的版本中,InnoDB存储引擎在数据库子目录下创建了一个专门用于存储表结构的文件,文件名是表名,文件扩展名是.frm,即表名.frm。下面在MySQL 5.7中创建数据库chapter2,在其中创建表student,SQL语句如下所示。

进入chapter2目录,查看文件,结果如下所示。可以看到,chapter2目录下包含student.frm和student.ibd文件。其中,student.frm文件用于存储表结构,该类型的文件在不同的平台上都是以二进制形式存储的;student.ibd文件用于存储数据。

同样,在MySQL 8.0中创建数据库chapter2,在其中创建表student,进入chapter2目录,查看文件,结果如下所示。可以看到,chapter2目录下只有一个student.ibd文件,.frm文件在MySQL 8.0中不复存在。那么,表结构被存储在哪里呢?

官方将.frm文件信息及更多信息移动到序列化字典信息(Serialized Dictionary Information,SDI)中,而SDI被写入.ibd文件中。

为了从.ibd文件中提取SDI,官方提供了一个应用程序ibd2sdi。这个应用程序不需要下载,MySQL 8.0自带,使用流程如下。

(1)进入数据库子目录,如下所示。

(2)执行ibd2sdi命令,如下所示。

(3)查看文件,结果如下所示,可以发现已经出现student.txt文件。

应用程序ibd2sdi会把.ibd文件里存储的表结构以JSON格式保存在student.txt文件中。student.txt文件中的内容如图2-1所示。图中标记部分从上到下分别表示表名、列、列名和列的长度。从上面的测试结果中可以发现,MySQL 8.0把以前版本中的.frm文件合并到.ibd文件中。

2.MyISAM存储引擎下表在文件系统中的表示

1)存储表结构

MyISAM存储引擎和InnoDB存储引擎一样,也在数据库子目录下创建了一个专门用于存储表结构的.frm文件。

2)存储数据和索引

MyISAM存储引擎中的索引全部是非聚簇索引(参见7.3.2节),该存储引擎中的数据和索引是分开存储的,这些文件都被存放在对应的数据库子目录下。如果表student使用MyISAM存储引擎,那么,在表student所在数据库对应的chapter2目录下会为该表创建3个文件,分别是student.frm、student.MYD(MY Data)和student.MYI(MY Index)。其中,student.frm文件用于存储表结构;student.MYD文件用于存储数据,也就是插入表中的记录;student.MYI文件是表的索引文件,我们为该表创建的索引都被存储在这个文件中。

图2-1 student.txt文件中的内容

在数据库chapter2中创建表student_myisam,使用ENGINE选项显式指定存储引擎为MyISAM,SQL语句如下所示。

首先查看MySQL 8.0中文件的存储形式,进入数据库子目录,结果如下所示。

可以看到,表student_myisam在文件系统中有3个文件。其中,student_myisam_371.sdi文件用于存储元数据;student_myisam.MYD文件用于存储数据;student_myisam.MYI文件用于存储索引。

在InnoDB存储引擎中,SDI与数据一起存储。而在MyISAM存储引擎和其他存储引擎中,SDI被写入数据目录下的.sdi文件中。

然后查看MySQL 5.7中文件的存储形式,进入数据库子目录,结果如下所示。

可以看到,表student_myisam在文件系统中也有3个文件。其中,student_myisam.frm文件用于存储表结构;student_myisam.MYD文件用于存储数据;student_myisam.MYI文件用于存储索引。

综上所述,在MySQL 8.0以前的版本中,MyISAM存储引擎下的表结构也被存储在.frm文件中;而在MySQL 8.0及以后的版本中,MyISAM存储引擎下的表结构被存储在.sdi文件中。

2.2.4 视图在文件系统中的表示

MySQL中的视图其实是虚拟的表,也就是某条查询语句的一个别名,因此,在存储视图的时候是不需要存储真实数据的,只需把视图结构存储起来即可。由于在MySQL 8.0中没有.frm文件,因此在数据目录下看不到视图的相关文件。

在MySQL 5.7中,视图和表一样,存储视图结构的文件也会被存放在对应的数据库子目录下,并且只会存放一个名为视图名的.frm文件。先使用如下语句创建视图。

再查看视图,结果如下所示。可以看到,在文件系统中只有student_view.frm文件,没有student_view.ibd文件。

2.2.5 其他文件

除了上面提到的文件,在数据目录下还有一些其他文件。

(1)服务器进程文件。每运行一个MySQL服务器端程序,都意味着启动一个进程。MySQL服务器会把MySQL实例全局唯一的server-uuid存放到auto.cnf文件中,如下所示。

(2)服务器日志文件。在服务器运行过程中,会产生各种各样的日志,如常规的查询日志、错误日志、二进制日志、redo日志等。这些日志各有用途,将在后面的章节中讲解。

(3)自动生成的SSL证书、RSA证书和密钥文件。