购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.5 MySQL物理文件体系结构

MySQL在Linux系统中的数据文件目录如图1-6所示,可以归结为如下几类。

图1-6

(1)binlog二进制日志文件:不管使用的是哪一种存储引擎,都会产生binlog。如果开启了binlog二进制日志,就会有若干个二进制日志文件,如mysql-bin.000001、mysql-bin.000002、mysql-bin.00003等。binlog记录了MySQL对数据库执行更改的所有操作。查看当前binlog文件列表,如图1-7所示。

图1-7

在MySQL 5.1之前,所有的binlog都是基于SQL语句级别的。应用这种格式的binlog进行数据恢复时,如果SQL语句带有rand或uuid等函数,可能导致恢复出来的数据与原始数据不一致。从MySQL 5.1版本开始,MySQL引入了binlog_format参数。这个参数有可选值statement和row:statement就是之前的格式,基于SQL语句来记录;row记录的则是行的更改情况,可以避免之前提到的数据不一致的问题。做MySQL主从复制,statement格式的binlog可能会导致主备不一致,所以要使用row格式。我们还需要借助mysqlbinlog工具来解析和查看binlog中的内容。如果需要用binlog来恢复数据,标准做法是用mysqlbinlog工具把binlog中的内容解析出来,然后把解析结果整个发给MySQL执行。

(2)redo重做日志文件:ib_logfile0、ib_logfile1是InnoDB引擎特有的、用于记录InnoDB引擎下事务的日志,它记录每页更改的物理情况。首先要搞明白的是已经有binlog了为什么还需要redo log,因为两者分工不同。binlog主要用来做数据归档,但是并不具备崩溃恢复的能力,也就是说如果系统突然崩溃,重启后可能会有部分数据丢失。Innodb将所有对页面的修改操作写入一个专门的文件,并在数据库启动时从此文件进行恢复操作,这个文件就是redo log file。redo log的存在可以完美解决这个问题。默认情况下,每个InnoDB引擎至少有一个重做日志组,每组下至少有两个重做日志文件,例如前面提到的ib_logfile0和ib_logfile1。重做日志组中的每个日志文件大小一致且循环写入,也就是说先写iblogfile0,写满了之后写iblogfile1,一旦iblogfile1写满了,就继续写iblogfile0。当innodb log设置过大的时候,可能会导致系统崩溃后恢复需要很长的时间;当innodb log设置过小的时候,在一个事务产生大量日志的情况下,需要多次切换重做日志文件。

(3)共享表空间和独立表空间:在MySQL 5.6.6之前的版本中,InnoDB默认会将所有的数据库InnoDB引擎的表数据存储在一个共享表空间ibdata1中,这样管理起来很困难,增删数据库的时候,ibdata1文件不会自动收缩,单个数据库的备份也将成为问题。为了优化上述问题,在MySQL 5.6.6之后的版本中,独立表空间innodb_file_per_table参数默认开启,每个数据库的每个表都有自已独立的表空间,每个表的数据和索引都会存在自己的表空间中。即便是innnodb表指定为独立表空间,用户自定义数据库中的某些元数据信息、回滚(undo)信息、插入缓冲(change buffer)、二次写缓冲(double write buffer)等还是存放在共享表空间,所以又称为系统表空间。

这个系统表空间由一个或多个数据文件组成,默认情况下其包含一个叫ibdata1的系统数据文件,位于MySQL数据目录(datadir)下。系统表空间数据文件的位置、大小和数目由参数innodb_data_home_dir和innodb_data_file_path启动选项控制。

当开启独立表空间参数innodb_file_per_table选项时,该表创建于自己的数据文件中,而非创建于系统表空间中。这样的好处在于在drop或者truncate时空间可以被收回至操作系统用作其他用途,而且进行单表空间在不同实例间移动,而不必处理整个数据库表空间。

如图1-8所示,参数innodb_file_per_table独立表空间选项开启,同时通过“show variables like 'innodb_data%';”命令可以查询共享表空间(系统表空间)的文件信息。

图1-8

(4)undo log:undo log是回滚日志,如果事务回滚,则需要依赖undo日志进行回滚操作。MySQL在进行事务操作的同时,会记录事务性操作修改数据之前的信息,就是undo日志,确保可以回滚到事务发生之前的状态。innodb的undo log存放在ibdata1共享表空间中,当开启事务后,事务所使用的undo log会存放在ibdata1中,即使这个事务被关闭,undo log也会一直占用空间。为了避免ibdata1共享表空间暴涨,建议将undo log单独存放。如图1-9所示,innodb_undo_directory参数指定单独存放undo表空间的目录,该参数实例初始化之后不可直接改动(可以通过先停库,修改配置文件,然后移动undo表空间文件的方式去修改该参数);innodb_undo_tablespaces参数指定单独存放的undo表空间个数,推荐设置为大于等于3;innodb_undo_logs参数指定回滚段的个数,默认为128个。MySQL 5.7引入了新的参数innodb_undo_log_truncate,这个参数开启后可在线收缩拆分出来的undo表空间。

图1-9

(5)临时表空间:存储临时对象的空间,比如临时表对象等。如图1-10所示,参数innodb_temp_data_file_path可以看到临时表空间的信息,上限设置为5GB。

图1-10

MySQL 5.7对于InnoDB存储引擎的临时表空间做了优化。在MySQL 5.7之前,InnoDB引擎的临时表都保存在ibdata里面,而ibdata的贪婪式磁盘占用导致临时表的创建与删除对其他正常表产生非常大的性能影响。

在MySQL 5.7中,对于临时表做了下面两个重要方面的优化:MySQL 5.7把临时表的数据从共享表空间里面剥离出来,形成自己单独的表空间,参数为innodb_temp_data_file_path;MySQL 5.7中把临时表的相关检索信息保存在系统信息表中:information_schema.innodb_temp_table_info。在MySQL 5.7之前的版本中,想要查看临时表的系统信息没有太好的办法。

虽然InnoDB临时表有自己的表空间,但是目前还不能自己定义临时表空间文件的保存路径,只能是继承innodb_data_home_dir。此时如果想要拿其他的磁盘(比如内存盘)来充当临时表空间的保存地址,只能用老办法做软链。

需要注意的一点就是:有时执行SQL请求时会产生临时表,极端情况下可能导致临时表空间文件暴涨,所以为了避免以后再出现类似的情况,一定要限制临时表空间的最大上限,超过上限时,需要生成临时表的SQL无法被执行(一般这种SQL效率也比较低,可借此机会进行优化)。

(6)errorlog:错误日志记录了MySQL Server每次启动和关闭的详细信息,以及运行过程中所有较为严重的警告和错误信息。如图1-11所示,可以用参数log-error[=file_name]选项来开启MySQL错误日志,该选项指定保存错误日志文件的位置。

图1-11

(7)slow.log:如果配置了MySQL的慢查询日志,MySQL就会将运行过程中的慢查询日志记录到slow_log文件中。MySQL的慢查询日志是MySQL提供的一种日志记录,用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL。如图1-12所示,参数slow_query_log_file指定慢查询日志文件的存放路径;参数long_query_time的默认值为10,意思是运行10s以上的语句。默认情况下,MySQL数据库并不启动慢查询日志,需要我们手动来设置这个参数。慢查询日志支持将日志记录写入文件,也支持将日志记录写入数据库表。

图1-12

(8)general_log:如图1-13所示,参数general_log=off表明没有启用通用查询日志,如果配置了通用查询日志,将记录建立的client连接和运行的语句。参数general_log_file表明通用查询日志位置及名字,MySQL将运行过程中的所有SQL都记录在此文件中。

图1-13

(9)数据库路径:可以看到系统数据库mysql、sys、performance_schema和用户自定义的数据库test、mldn(展开具体的路径之后是具体的每个数据库自己的对象)。

①系统数据库:系统数据库包括以下几种。

②用户数据库:用户数据库(如mldn)实际上是一个目录,保存了数据库中的表以及数据信息。图1-14是一个典型的数据库目录下的文件信息。对于InnoDB引擎的表,InnoDB为独立表空间模式,每个数据库的每个表都会生成一个数据空间(而不是在共享表空间ibdata1文件中)。例如,member表分别对应两个文件:一个是member.frm,存储的是表结构信息;另一个是member.ibd,存储的是表中的数据。同理,customers表也是两个文件。另外,还有一个db.opt文件,是用来记录该库的默认字符集编码和字符集排序规则的。

图1-14 /X1B7xdoD2suLCXa+22yhzSs2cIMrfuQQgVBIgzfcK09ZrDid69JvNIN+JhRtBVP

点击中间区域
呼出菜单
上一章
目录
下一章
×