简介在数据库中,日志文件记录了数据库运行的方方面面信息,对数据库的正常运行起着重要的作用。在MySQL数据库中,主要包括Redolog日志、Undolog日志、Binlog日志、Relaylog日志、GeneralQueryLog日志、SlowQueryLog日志和Errorlog日志。这些日志共同构成了MySQL数据库的日志系统。在本文中,将对这些日志的作用一一进行介绍。1、事务日志在MySQLInnoDB引擎中,事务日志主要由两部分组成,分别是Redolog和Undolog。其中,Redolog也称为重做日志,用于保证事务的原子性和持久性,以及在崩溃恢复时纠正未完成事务写入的数据。Undolog主要记录数据变化的原像信息,用于实现事务回滚和MVCC功能。1.1.Redolog的基本概念Redolog主要包括两部分:1)RedoLogBuffer(日志缓冲区),这是一块位于内存中的区域,主要用于缓存要写入磁盘日志文件的数据。2)RedoLogFile,位于磁盘上,将日志数据持久化到LogBuffer中。建库后,默认会创建两个名为ib_logfile0和ib_logfile1的文件。为了保证日志的持久化,InnoDB存储引擎实现了ForceLogatcommit机制,即当一个事务被提交时,首先要将该事务的所有日志写入redolog。在InnoDB的默认设置(innodb_flush_method)下,每次将RedoLogBuffer中的日志更新到磁盘中的日志文件时,先将redologbuffer写入文件系统缓存,然后操作系统的fsync操作调用写入Redolog文件,流程如下图所示。图1Logbuffertologfilewriteprocess针对严格遵守ACID特性和磁盘IO性能权衡的问题,MySQLInnoDB引擎中还有一个参数innodb_flush_log_at_trx_commit,用于控制flushlogs的策略在Logbuffer到磁盘。策略如下:1)当设置为1(默认)时,Logbuffer中的日志会被写入操作系统缓存,每次事务提交时都会调用fsync写入Redo日志文件。这样可以确保每个事务日志都不会丢失。2)设置为0时,事务提交时不会将Logbuffer中的日志fsync到Redo日志文件中,而是按照innodb_flush_log_at_timeout(default=1)参数设置的固定时间频率(s),定期将日志缓冲区日志持久化到重做日志文件。这样就有可能在非正常宕机的时候不小心丢失了部分重做日志,导致事务日志丢失了部分。3)设置为2时,Logbuffer中的日志会在事务提交时写入Redo日志文件,但只写入文件系统的缓存中,不进行fsync操作。这样就无法完全保证一个事务中所有日志的完整性。如果系统宕机,未同步到磁盘的日志可能会丢失。1.2Undolog的基本概念Undolog是与单个读写事务关联的undolog记录的集合,undolog记录包含了如何撤销该事务对聚集索引记录的最新更改的信息。Undolog存放在数据库内部一个特殊的段(segment)中,叫做undolog,位于共享表空间中。Undolog主要实现了数据库中的两个功能,事务回滚和MVCC。2、BinlogBinlog(二进制日志)是由MySQLServer层维护的二进制日志。主要记录数据库中所有的DDL操作和DML操作,但Binlog中不记录SELECT、SHOW等查询。Binlog语句是基于“事务”存储在磁盘上的。2.1主要功能1)Replication:在MySQL源上开启Binlog,将source产生的binlog发送给slave,然后从slave回放日志,实现与源数据的一致性。2)数据恢复:通过Binlog日志实现指定时间点的数据恢复。2.2Binlog日志格式在my.cnf文件中设置log_bin=/DIRECTORY_NAME/file_name参数启用。Binlog日志主要有三种格式,可以通过my.cnf文件中的-binlog_format参数设置。1)STATEMENT基于SQL语句模式,日志中记录的是执行语句和上下文。这种模式下产生的日志量较少,因此对磁盘IO的影响降低,性能提升。2)ROW的基于行的模式会在日志中记录每一行的变化。与语句格式相比,日志内容要大得多,对磁盘IO的影响也更大。但是由于记录了每一行数据修改的细节,所以不会出现某些情况下从库无法复制的情况。3)MIXED混合模式,即Statement和Row日志格式的混合,是MySQL默认的日志格式。在混合模式下,MySQL会默认使用基于SQL语句的日志记录方式(Statement),但在某些特殊场景下会自动切换到基于行的日志记录方式。3、中继日志中继日志(relaylog)是MySQL主从复制过程中产生的日志。MySQL中的主从复制主要涉及三个线程:1)Logdump线程:将主库的数据传输到从库Binlog日志的IO线程2)IO线程:向主库请求Binlog日志,以及将Binlog日志写入本地relaylog。3)SQL线程:读取Relay日志,解析成SQL语句,一条一条执行。图2从图2可以看出,从库的IO线程接收到主库logdump线程投递的Binlog日志后,会写入本地日志,即Relaylog。在文件目录中,一般由多个host_name-relay-bin.nnnnnn日志文件和host_name-relay-bin.index索引文件组成。日志文件记录了事务中数据修改的信息,索引文件记录了使用过的日志文件信息。Relaylog的日志格式和Binlog一致,但是比Binlog多了两个日志,master.info和relay-log.info(默认存放在data文件目录下)。master.info主要记录了master上次读取同步的binlog的位置,slave节点的连接信息和master节点信息,以及连接master和开始复制所需要的所有信息。relay-log.info主要记录从节点拷贝文件的进度,下一个事件从哪里开始,sql线程负责更新。4、通用查询日志通用查询日志(GeneralQueryLog)记录了用户的所有操作,包括启动和关闭MySQL服务,添加、删除、修改和查询语句。需要注意的是,binlog中并没有记录查询日志。默认情况下,此日志处于关闭状态。相关参数如下:general_log=[0|1]--0为off,1为onlog-output=[TABLE|FILE|NONE]--设置日志输出对象general_log_file=[FILENAME]--设置输出日志名称5.SlowQueryLogSlowQueryLog(慢查询日志)由SQL语句组成。记录所有执行时间超过参数log_query_time(秒)且扫描记录数不小于min_examined_row_limit的SQL语句的日志。慢查询日志主要用于查找执行时间较长的语句。默认情况下,不使用索引的管理语句和查询语句不会记录在slowquery日志中,但是可以通过设置参数log_slow_admin_statements和log_queries_not_using_indexes来监控这两类语句。在MySQL中,管理语句定义为ALTERTABLE、ANALYZETABLE、CHECKTABLE、CREATEINDEX、DROPINDEX、OPTIMIZETABLE和REPAIRTABLE。如果从文本日志中搜索一些慢查询语句,会非常耗时。MySQL推荐使用mysqldumpslow工具对慢查询日志进行分类汇总。相关参数如下:long_query_time=10--默认为10s,最小值为0slow_query_log[={0|1}]--也可以是布尔值(ON|OFF),默认为0,并且日志被关闭。slow_query_log_file=file_name--指定慢查询日志文件的名称,默认host_name-slow.loglog-output=[TABLE|FILE|NONE]-设置日志输出对象6.错误日志ErrorLog(错误日志)包含mysqld的记录启动和关闭时间,以及诊断消息,例如在服务器启动和关闭期间以及服务器运行时出现的错误、警告和注意事项。当数据库因为故障无法运行时,可以通过查看日志来分析问题。相关参数如下:log-error[=file_name]--设置日志名称总结MySQL数据库的日志系统是一个比较大的系统。本文只简单介绍一些常见的日志。在使用和参数设置上还有很多细节,大家也可以参考官方文档进行详细学习。
