概述
本章将分析构成MySQL数据库和InnoDB存储引擎表的各种类型文件。这些文件有以下这些。
- 参数文件:告诉MySQL实例启动时在哪里可以找到数据库文件,并且指定某些初始化参数,这些参数定义了某种内存结构的大小等设置,还会介绍各种参数的类型。
- 日志文件:用来记录MySQL实例对某种条件做出响应时写入的文件,如错误日志文件、二进制日志文件、慢查询日志文件、查询日志文件等。
- socket文件:当UNIX域套接字方式进行连接时需要的文件。
- pid文件:MySQL实例的进程ID文件。
- MySQL表结构文件:用来存放MySQL表结构定义文件。
- 存储引擎文件:因为MySQL表存储引擎的关系,每个存储引擎都会有自己的文件来保存各种数据。这些存储引擎真正存储了记录和索引等数据。本章主要介绍与InnoDB有关的存储引擎文件。
参数文件
当MySQL实例启动时,数据库会先去读一个配置参数文件,用来寻找数据库的各种文件所在的位置以及指定某些初始化参数,这些参数通常定义了某种内存结构有多大等。在默认情况下,MySQL实例会按照一定的顺序在指定的位置进行读取,用户只需要通过命令mysql --help | grep my.cnf来寻找即可。
参数类型
MySQL数据库中的参数可以分为两类:
- 动态(dynamic)参数
- 静态(static)参数
动态参数意味着可以在MySQL实例运行中进行更改,静态参数说明在整个实例生命周期内都不得进行更改,就好像是只读的。可以通过SET命令对动态的参数值进行修改,SET语法如下:
SET
| [global | session] system_var_name = expr |
| [@@global. | @@session.] @@]system_var_name = expr |
这里可以看到global和session关键字,它们表明该参数的修改是基于当前会话还是整个实例的生命周期。有些动态参数只能在会话中进行修改。而有些参数修改完后,在整个实例生命周期中都会生效。而有些参数既可以在会话中又可以在整个实例的生命周期内生效。
日志文件
日志文件记录了影响MySQL数据库的各种类型活动。MySQL数据库中常见的日志文件有:
- 错误日志(error log)
- 二进制日志(binlog)
- 慢查询日志(slow query log)
- 查询日志(log)
这些日志文件可以帮助DBA对MySQL数据库的运行状态进行诊断,从而更好地进行数据库层面的优化。
错误日志
错误日志文件对MySQL的启动、运行、关闭过程进行了记录。该文件不仅记录了所有的错误信息,也记录一些警告信息或正确的信息。用户可以通过命令SHOW VARIABLES LIKE 'log_error’来定位该文件。
慢查询日志
慢查询日志(slow log)可以帮助DBA定位可能存在问题的SQL语句,从而进行SQL语句层面的优化。在默认情况下,MySQL数据库并不启动慢查询日志,用户需要手工将这个参数设置为ON。
这里有两点需要注意。首先,设置long_query_time这个阈值后,MySQL数据库会记录运行时间超过该值的所有SQL语句,但运行时间正好等于long_query_time的情况并不会被记录下。
另一个和慢查询日志有关的参数是log_queries_not_using_indexes,如果运行的SQL语句没有使用索引,则MySQL数据库同样会将这条SQL语句记录到慢查询日志文件。
MySQL5.6.5版本开始新增了一个参数log_throttle_queries_not_using_indexes,用来表示每分钟允许记录到slow log的且未使用索引的SQL语句次数。该值默认为0,表示没有限制。在生产环境下,若没有使用索引,此类SQL语句会频繁记录到slow log,从而导致slow log文件的大小不断增加。
查询日志
查询日志记录了所有对MySQL数据库请求的信息,无论这些请求是否得到了正确的执行。默认文件名为:主机名.log。
二进制日志
二进制日志(binary log)记录了MySQL数据库执行更改的所有操作,但是不包括SELECT和SHOW这类操作,因为这类操作对数据本身并没有修改。然而,若操作本身并没有导致数据库发生变化,那么该操作可能也会写入二进制日志。
如果用户想记录SELECT和SHOW操作,那只能使用查询日志,而不是二进制日志。此外,二进制日志还包括了执行数据库更改操作的时间等其他额外信息。总的来说,二进制日志主要有以下几种作用。
- 恢复(recovery):某些数据的恢复需要二进制日志。
- 复制(replication):其原理与恢复类似,通过复制和执行二进制日志使一台远程的MySQL数据库(一般称为slave或standby)与一台MySQL数据库(一般称为master或primary)进行实时同步。
- 审计(audit):用户可以通过二进制日志中的信息来进行审计,判断是否有对数据库进行注入攻击。
通过配置参数log-bin [=name]可以启动二进制日志。如果不指定name,则默认二进制日志文件名为主机名,后缀名为二进制日志的序列号,所在路径为数据库所在目录(datadir)。
二进制日志文件在默认情况下并没有启动,需要手动指定参数来启动。以下配置文件的参数影响着二进制日志记录的信息和行为:
- max_binlog_size
- binlog_cache_size
- sync_binlog
- binlog_do_db
- binlog-ignore-db
- log-slave-update
- binlog_format
参数max_binlog_size指定了单个二进制日志文件的最大值,如果超过该值,则产生新的二进制日志文件,后缀名+1,并记录到.index文件。
当使用事务的表存储引擎(如InnoDB存储引擎)时,所有未提交(uncommitted)的二进制日志会被记录到一个缓存中去,等该事务提交(committed)时直接将缓冲中的二进制日志写入二进制日志文件,而该缓冲的大小由binlog_cache_size决定,默认为32K。此外,binlog_cache_size是基于会话(session)的,也就是说,当一个线程开始一个事务时,MySQL会自动分配一个大小为binlog_cache_size的缓存,因此该值的设置需要相当小心,不能设置过大。当一个事务的记录大于设定的binlog_cache_size时,MySQL会把缓冲中的日志写入一个临时文件中,因此该值又不能设置的太小。通过SHOW GLOBAL STATUS命令查看binlog_cache_size、binlog_cache_disk_use的状态,可以判断当前binlog_cache_size的设置是否合适。binlog_cache_use记录了使用缓冲写二进制日志的次数,binlog_cache_disk_use记录了使用临时文件写二进制日志的次数。
在默认情况下,二进制日志并不是每次写的时候同步磁盘(用户可以理解为缓冲写)。因此,当数据库所在操作系统发生宕机时,可能会有最后一部分数据没有写入到二进制日志文件中,这会给恢复和复制带来问题。参数sync_binlog=[N]表示每写缓冲多少次就同步到磁盘。如果将N设为1,表示采用同步写磁盘的方式来写二进制日志,这时写操作不使用操作系统的缓冲来写二进制日志。sync_binlog的默认值为0,如果使用InnoDB存储引擎进行复制,并且想得到最大的高可用性,建议将该值设为ON。不过该值ON时,确实会对数据库IO带来一定的影响。
但是,即使将sync_binlog设为1,还是会有一种情况导致问题发生。当使用InnoDB存储引擎时,在一个事务发出COMMIT动作之前,由于sync_binlog为1,因此会将二进制日志立即写入磁盘。如果这时已经写入了二进制日志,但是提交还没有发生,并且此时发生了宕机,那么在MySQL数据库下次启动时,由于COMMIT操作并没有发生,这个事务会被回滚掉。但是二进制日志已经记录了该事务信息,不能被回滚。这个问题可以通过将参数innodb_support_xa设为1来解决,虽然innodb_support_xa与XA事务有关,但它同时也确保了二进制日志和InnoDB存储引擎数据文件的同步。
参数binlog-do-db和binlog-ignore-db表示需要写入或忽略写入哪些库的日志。默认为空,表示需要同步所有库的日志到二进制日志。
如果当前数据库是复制中的slave角色,则它不会将从master取得并执行二进制日志写入到自己的二进制日志文件中去。如果需要写入,要设置log-slave-update。如果需要搭建master->slave->slave架构的复制,则必须设置该参数。
binlog_format参数十分重要,它影响了记录二进制日志的格式。所有二进制文件的格式都是基于SQL语句(statement)级别的。
从MySQL5.1开始引入了binlog_format参数,该参数可设的值有STATEMENT、ROW和MIXED。
(1)、STATEMENT格式和之前的MySQL版本一样,二进制日志文件记录的是日志的逻辑SQL语句。
(2)、在ROW格式下,二进制日志记录的不再是简单的SQL语句了,而是记录表的行更改情况。
(3)、在MIXED格式下,MySQL默认采用STATEMENT格式进行二进制日志文件的记录,但是在一些情况下会使用ROW格式,可能的情况有:
1、表的存储引擎为NDB,这时对表的DML操作都会以ROW格式记录。
2、使用了UUID()等不确定函数。
3、使用了INSERT DELAY语句。
4、使用了用户定义函数(UDF)。
5、使用了临时表(temporary table)。
套接字文件
pid文件
表结构定义文件
InnoDB存储引擎文件
表空间文件
InnoDB采用将存储的数据按表空间(tablespace)进行存放设计。在默认配置下会有一个初始大小为10MB,名为ibdata1的文件。该文件就是默认的表空间文件(tablespace file),用户可以通过参数innodb_data_file_path对其进行设置。