mysql系统日志 (binlog, redolog, undolog, errorlog, generallog, relaylog, slowquerylog)

1.错误日志 errorlog


错误日志记录着mysqld服务在启动,停止,和运行过程中发生的错误及警告相关信息。
log_error参数控制错误日志是否写入文件及文件名称,默认情况下,错误日志被写入终端标准输出stderr

[mysqld]
log_error = /data/mysql/logs/error.log



2.慢查询日志 slow query log

慢查询日志是用来记录执行时间超过 long_query_time 这个变量定义的时长的查询语句。默认情况下,慢查询日志是不开启的。

在配置文件中可以增加以下参数:
slow_query_log :是否启用慢查询日志,默认为0,可设置为0,1。
slow_query_log_file :指定慢查询日志位置及名称,默认值为host_name-slow.log,可指定绝对路径。
long_query_time :慢查询执行时间阈值,超过此时间会记录,默认为10,单位为s。
log_output :慢查询日志输出目标,默认为file,即输出到文件。

3、一般查询日志 general log

一般查询日志(通用查询日志),是MySQL中记录最详细的日志,该日志会记录mysqld所有相关操作。当clients 连接或断开连接时,服务器将信息写入此日志
并记录从 clients 收到的每个 SQL 语句。默认情况下,general log 是关闭的,开启通用查询日志会增加很多磁盘 I/O。
相关参数配置如下:
[mysqld]
general_log = 0 //默认值是0,即不开启,可设置为1
general_log_file = /data/mysql/logs/general.log //指定日志位置及名称


4、中继日志 relay log


中继日志用于主从复制架构中的<从服务器>上<从服务器>的 slave 进程从<主服务器>处获取二进制日志的内容并写入中继日志,然后由 IO 进程读取并执行中继日志中的语句。
相关参数一般在从库设置,几个相关参数:

relay_log :定义 relay log 的位置和名称。
relay_log_purge :是否自动清空不再需要中继日志,默认值为1(启用)。
relay_log_recovery :当 slave 从库宕机后,假如 relay log 损坏了,导致一部分中继日志没有处理,则自动放弃所有未执行的 relay log ,并且重新从 master 上获取日志。
默认情况下该功能是关闭的,将 relay_log_recovery 的值设置为1可开启此功能。
relay log 默认位置在数据文件的目录,文件名为 host_name-relay-bin,可以自定义文件位置及名称。
[mysqld]
relay_log = /data/mysql/logs/relay-bin
relay_log_purge = 1
relay_log_recovery = 1


5、二进制日志 binlog


binlog 是 MySQL 最重要的日志,它以事件形式记录了所有的 DDL 和 DML 语句(除select、show等),还包含语句所执行的消耗的时间,MySQL的二进制日志是事务安全型的。
binlog 的主要目的是复制和恢复。

bin log是mysql数据库service层的,是所有存储引擎共享的日志模块,它用于记录数据库执行的写入性操作也就是在事务commit阶段进行记录,以二进制的形式保存于磁盘中。
bin log是逻辑日志,并且由mysql数据库的service层执行,也就是说使用所有的存储引擎数据库都会记录bin log日志。
bin log是以追加的方式进行写入的,可以通过 max_binlog_size 参数设置bin log文件大小,
当文件大小达到某个值时,会生成新的文件来保存日志。

一般来说开启binlog日志大概会有1%的性能损耗。
启用binlog,通过配置 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf 配置文件的 log-bin 选项:

在配置文件中加入 log-bin 配置,表示启用binlog,如果没有给定值,写成 log-bin=,则默认名称为主机名。(注:名称若带有小数点,则只取第一个小数点前的部分作为名称)
也可以通过 SET SQL_LOG_BIN=1 命令来启用 binlog,通过 SET SQL_LOG_BIN=0 命令停用 binlog。启用 binlog 之后须重启MySQL才能生效。

Binlog 的日志格式
记录在二进制日志中的事件的格式取决于二进制记录格式。支持三种格式类型:

STATEMENT:基于SQL语句的复制(statement-based replication, SBR)
ROW:基于行的复制(row-based replication, RBR)
MIXED:混合模式复制(mixed-based replication, MBR)
在 MySQL 5.7.7 之前,默认的格式是 STATEMENT,在 MySQL 5.7.7 及更高版本中,默认值是 ROW。
日志格式通过 binlog-format 指定,如 binlog-format=STATEMENT、binlog-format=ROW、binlog-format=MIXED。
Statement
每一条会修改数据的sql都会记录在binlog中

优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO, 提高了性能。
缺点:由于记录的只是执行语句,为了这些语句能在slave上正确运行,因此还必须记录每条语句在执行的时候的一些相关信息,
以保证所有语句能在slave得到和在master端执行的时候相同的结果。另外mysql的复制,像一些特定函数的功能,slave与master要保持一致会有很多相关问题。

Row
5.1.5版本的MySQL才开始支持 row level 的复制,它不记录sql语句上下文相关信息,仅保存哪条记录被修改。

优点: binlog中可以不记录执行的sql语句的上下文相关的信息,仅需要记录那一条记录被修改成什么了。
所以row的日志内容会非常清楚的记录下每一行数据修改的细节。而且不会出现某些特定情况下的存储过程,或function,以及trigger的调用和触发无法被正确复制的问题.
缺点:所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容。

注:将二进制日志格式设置为ROW时,有些更改仍然使用基于语句的格式,包括所有DDL语句,例如CREATE TABLE, ALTER TABLE,或 DROP TABLE。

Mixed
从5.1.8版本开始,MySQL提供了Mixed格式,实际上就是Statement与Row的结合。
在Mixed模式下,一般的语句修改使用statment格式保存binlog,如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog,
MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。


bin log刷盘机制
对于InnoDB引擎而言,在每次事务commit提交时才会记录bin log日志,此时记录仍然在内存中,mysql通过 sync_binlog 参数控制bin log刷盘时机,取值范围:0~N:
0:不去强求,由系统自行判断何时写入磁盘;
1:每次事务commit的时候都要将bin log写入磁盘;
N:每N个事务commit,才会将bin log写入磁盘;

sync_binlog 参数建议设置为1,这样每次事务commit时就会把bin log写入磁盘中,这样也可以保证mysql异常重启之后bin log日志不会丢失。


bin log使用场景
在实际场景中, bin log 的主要场景有两点,一点是主从复制,另一点是数据恢复
主从复制:在master端开启 bin log ,然后将 bin log 发送给各个slaver端,slaver端读取 bin log 日志,从而使得主从数据库中数据一致
数据恢复:通过 bin log 获取想要恢复的时间段数据

常用的Binlog操作命令
# 是否启用binlog日志
show variables like 'log_bin';

# 查看详细的日志配置信息
show global variables like '%log%';

# mysql数据存储目录
show variables like '%dir%';

# 查看binlog的目录
show global variables like "%log_bin%";

# 查看当前服务器使用的biglog文件及大小
show binary logs;

# 查看主服务器使用的biglog文件及大小

# 查看最新一个binlog日志文件名称和Position
show master status;


事件查询命令
# IN 'log_name' :指定要查询的binlog文件名(不指定就是第一个binlog文件)
# FROM pos :指定从哪个pos起始点开始查起(不指定就是从整个文件首个pos点开始算)
# LIMIT [offset,] :偏移量(不指定就是0)
# row_count :查询总条数(不指定就是所有行)
show binlog events [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count];

查看 binlog 内容
show binlog events;

查看具体一个binlog文件的内容 (in 后面为binlog的文件名)
show binlog events in 'master.000003';

设置binlog文件保存事件,过期删除,单位天
set global expire_log_days=3;

删除当前的binlog文件
reset master;

删除slave的中继日志
reset slave;

删除指定日期前的日志索引中binlog日志文件
purge master logs before '2019-03-09 14:00:00';

删除指定日志文件
purge master logs to 'master.000003';


6.重做日志 redo log

重做日志(redo log)的作用是确保事务的持久性,防止在发生故障的时间点,尚有脏页未写入磁盘。在重启 MySQL 服务的时候,根据 redo log 进行重做
从而达到事务的持久性这一特性。
redo log 记录了 sql 语句以及其他 api,对表数据产生的变化。redo log记录的是数据的物理变化,这也是它和 binlog 一个最大的区别
binlog 记录的是数据的逻辑变化,这也是为什么 redo log 可以用来 crash recovery,而 binlog 不能的原因之一。
事务开始之后就产生 redo log,redo log 的落盘并不是随着事务的提交才写入的,而是在事务的执行过程中,便开始写入 redo log 文件中。当对应事务的脏页写入到磁盘之后,
redo log 的使命也就完成了,重做日志占用的空间就可以重用(被覆盖)。

由于redo log记录的是数据页的变更,而这种记录是没有必要永久保存的,因此redo log实现上采用来大小固定,循环写入的方式,当记录写到末尾时,又会从头开始写。

redo log 是存储在磁盘的,用于 crash recovery 后修正数据的,也就是我们常说的故障恢复,比如掉电,宕机等等

redo log 默认有两个文件
redo log 是循环写的(circular)
innodb_log_file_size:设置每个 redo log 文件的大小,默认是 50331648 byte,也就是 48 MB
innodb_log_files_in_group:设置 redo log 文件的数量,默认是 2,最大值是 100

重做日志是在事务开始之后逐步写入重做日志文件,而不一定是事务提交才写入重做日志缓存。重做日志有一个缓存区 Innodb_log_buffer,Innodb_log_buffer 的默认大小为 8M
Innodb 存储引擎先将重做日志写入 innodb_log_buffer 中。然后会通过以下三种方式将 Innodb 日志缓冲区的日志刷新到磁盘:

Master Thread 每秒一次执行刷新 Innodb_log_buffer 到重做日志文件。
每个事务提交时会将重做日志刷新到重做日志文件。
当重做日志缓存可用空间少于一半时,重做日志缓存被刷新到重做日志文件。
由此可以看出,重做日志通过不止一种方式写入到磁盘,尤其是对于第一种方式,Innodb_log_buffer 到重做日志文件是 Master Thread 线程的定时任务。

因此重做日志的写盘,并不一定是随着事务的提交才写入重做日志文件的,而是随着事务的开始,逐步开始的。


7.回滚日志 undo log

undo log 是回滚日志,是记录每条数据的所有版本,比如 update 语句,那么它首先会将该条记录的数据记录到undo log日志中,并且将最新版本的roll_pointer指针指向上一个版本,
这样就可以形成当前记录的所有版本,这也是MVCC的实现机制。

上一篇:MVCC


下一篇:Mysql事务篇