数据目录


  • 数据目录

    数据目录是用来存储MySQL在运行过程中产生的数据,当想读取数据的时候,这些存储引擎会从文件系统中把数据读出来返回给我们,当想写入数据的时候,这些存储引擎会把这些数据又写回文件系统。文件系统是由操作系统来管理磁盘

    数据目录和安装目录是两个不同的目录,安装目录下存储着各种可执行文件。通过此命令SHOW VARIABLES LIKE 'datadir';可以查看数据目录

    每个数据库都对应数据目录下的一个子目录,每当新建一个数据库时,MySQL做两件事:

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

    2. 在该与数据库名同名的子目录下创建一个名为db.opt的文件,这个文件中包含了该数据库的各种属性,例如:数据库的字符集和比较规则

    数据目录下还包括为了更好运行程序的一些额外文件,主要包括这几种类型的文件:

    1. 服务器进程文件

      每运行一个MySQL服务器程序,都意味着启动一个进程。MySQL服务器会把自己的进程ID写入到一个文件中

    2. 服务器日志文件

      在服务器运行过程中,会产生各种各样的日志,例如:常规的查询日志、错误日志、二进制日志、redo日志等等,这些日志各有各的用途

    3. 默认/自动生成的SSL和RSA证书和密钥文件

      主要是为了客户端和服务器安全通信而创建的一些文件


  • 表在文件系统中

    每个表的信息分为两种:

    1. 表结构
    2. 表中数据

    表结构就是表的名称、表里的列、每个列的数据类型、约束条件、索引、字符集、比较规则等信息,这些信息都体现在建表语句中。为了保存这些信息,InnoDB和MyISAM这两种存储引擎都在数据目录下对应的数据库子目录下创建了一个专门用于描述表结构的文件,文件名是表名.frm。同时MySQL中的视图就是虚拟的表,所以在存储视图的时候是不需要存储真实的数据的,只需要把它的结构存储起来。和表一样,描述视图结构的文件也会被存储到所属数据库对应的子目录下,只会存储一个视图名.frm的文件

    表中数据的存储不同的存储引擎对应不同的的存储方法。InnoDB是使用页为基本单位来管理存储空间的,一个页的的大小16k,对于InnoDB存储引擎来说,每个索引都对应着一棵B+树,该B+树的每个节点都是一个数据页,数据页之间不一定是物理连续的,数据页之间有双向链表来维护着这些页的顺序。对于页的管理是通过表空间来管理,表空间是抽象的概念,表空间对应文件系统上一个或多个真实文件(不同表空间对应的文件数量可能不同)。每一个表空间可以被划分为很多很多很多个页,我们的表数据就存放在某个表空间下的某些页里。表空间有多个类型,如:系统表空间system tablespace、独立表空间file-per-table tablespace、通用表空间general tablespace、undo表空间undo tablespace、临时表空间temporary tablespace等。

    系统表空间

    InnoDB会在数据目录下创建一个名为ibdata1、大小为12M的文件,这个文件就是对应的系统表空间在文件系统上的表示。这个文件是自扩展文件,也就是当不够用的时候它会自己增加文件大小。可以在启动项里指定系统表空间的路径、大小,像这样:

      [server]
      innodb_data_file_path=sys_table_space1:512M;sys_table_space2:512M:autoextend
    

    在一个MySQL服务器中,系统表空间只有一份。从MySQL5.5.7~MySQL5.6.6之间的各个版本中,我们表中的数据都会被默认存储到这个系统表空间

    独立表空间

    在MySQL5.6.6以及之后的版本中,InnoDB并不会默认的把各个表的数据存储到系统表空间中,而是为每一个表建立一个独立表空间,也就是说我们创建了多少个表,就有多少个独立表空间。使用独立表空间来存储表数据的话,会在该表所属数据库对应的子目录下创建一个表示该独立表空间的文件,文件名和表名相同,即:表名.ibd。所以在数据库对应的子目录下会有两个与表同名的文件:

    1. 表名.frm
    2. 表名.ibd

    同时也可以在启动项里指定数据存储在系统表空间还是独立表空间:

      [server]
      innodb_file_per_table=0
    

    当innodb_file_per_table的值为0时,代表使用系统表空间;当innodb_file_per_table的值为1时,代表使用独立表空间。不过innodb_file_per_table参数只对新建的表起作用,对于已经分配了表空间的表并不起作用

    可以将表在系统表空间和独立表空间之间移动:

      // 系统表空间中的表转移到独立表空间
      ALTER TABLE 表名 TABLESPACE [=] innodb_file_per_table;
    
      // 独立表空间的表转移到系统表空间
      ALTER TABLE 表名 TABLESPACE [=] innodb_system;
    

    MyISAM存储引擎存储表中数据没有表空间概念,MyISAM中的索引全部都是二级索引,该存储引擎的数据和索引是分开存放。所以在文件系统中也是使用不同的文件来存储数据文件和索引文件。例如test表使用MyISAM存储引擎,那么在它所在数据库子目录下会为test表创建三个文件:

    1. test.frm
    2. test.MYD
    3. test.MYI

    test.MYD代表数据文件;test.MYI代表表的索引文件


  • 系统数据库简介

    我们查看MySQL数据库列表时发现几个并不是我们自己创建的数据库,这几个数据库包含了MySQL服务器运行过程中所需的一些信息以及一些运行状态信息

    • mysql

      它存储了MySQL的用户账户和权限信息,一些存储过程、事件的定义信息,一些运行过程中产生的日志信息,一些帮助信息以及时区信息等

    • information_schema

      这个数据库保存着MySQL服务器维护的所有其他数据库的信息,例如:表、视图、触发器、列、索引等等。这些信息并不是真实的用户数据,而是一些描述性信息,也称之为元数据

    • performance_schema

      这个数据库里主要保存MySQL服务器运行过程中的一些状态信息,算是对MySQL服务器的一个性能监控。包括统计最近执行了哪些语句,在执行过程的每个阶段都花费了多长时间,内存的使用情况等等信息

    • sys

      这个数据库主要是通过视图的形式把information_schema和performance_schema结合起来,让程序员可以更方便的了解MySQL服务器的一些性能信息