MySQL日志(4)- binlog

最后更新:2018-06-29

二进制日志(binlog) 记录了所有 DDL 语句和 DML 语句,但是不包括数据查询语句。语句以“事件”的形式保存,它描述了数据的更改过程。在主从复制中,从库利用主库上的binlog进行重播,实现主从同步;此日志对于灾难时的数据恢复起着极其重要的作用。

server层实现的,意味着所有引擎都可以使用binlog日志

1. 日志的位置和格式

当用 –log-bin[=file_name] 选项启动时,mysqld 开始将数据变更情况写入日志文件。如果灭有给出 file_name 值,默认名为主机名后面跟“-bin”。如果给出了文件名,但没有包含路径,则文件默认被写入参数 datadir(数据目录)指定的目录。

二进制日志的格式分为 3 种:statement、row、mixed,可以在启动时通过参数 –binlog_format 进行设置,这 3 种格式的区别如下:

STATEMENT

mysql 5.1 之前的版本都采用这种方式,日志中记录的都是语句(statement),每一条对数据造成修改的sql语句都会记录到日志中,通过 mysqlbinlog 工具,可以清晰的看到每条语句的文本。主从复制时,从库(slave)会将日志解析为原文本,并在从库中重新执行一次。

【优点】:日志记录清晰易读,不需要记录每一行的变化,减少了 bin log 日志量,节约了 IO , 从而提高了性能

【缺点】:在某些情况下会导致主从数据不一致,比如执行sysdate()、slepp()等

针对与原数据(即未修改)相同的update语句会在MySQL内部重新执行

ROW

mysql 5.1.11 之后,出现了这种新的日志格式,它将每一行的变更记录到日志中,而不是记录sql语句,比如一个简单的跟新sql: update emp set name='abc' 如果是 statement 格式,日志中会记录一行 sql 文本; 如果是 row 格式,由于是对全表进行更新,也就是每一行记录都会发生改变,如果是一个 100 万行的大表,则日志中会记录 100万条记录的变化情况。日志量大大增加。

【优点】:是会记录每一行数据变化的细节,不会出现某些特定情况下的存储过程、或 function、或 trigger 的调用和触发无法被正确复制的问题

【缺点】:会产生大量的日志,尤其是 alter table 的时候会让日志暴涨

针对与原数据(即未修改)相同的update语句不会在MySQL内部重新执行(innodb引擎可以发现数据相同)

MIXED

这是目前 MySQL 默认的日志格式,即混合了 statement 和 row 两种日志。对于绝大部分操作,都使用 STATEMENT 来进行 binlog 的记录,只有以下操作使用 ROW 来实现:表的存储引擎为 NDB,使用了uuid() 等不确定函数,使用了 insert delay 语句,使用了临时表

注意:可以在 global 和 session 级别对 binlog_format 进行日志格式设置,但一定要谨慎操作,确保从库的复制能够正常进行。

2. 日志的读取与删除

由于日志以二进制方式存储,不能直接读取,需要用 mysqlbinlog 工具来查看,对于 statement 格式的文件可以用工具直接查看,对于 row 格式的要加 -v 或 -vv 参数进行读取。

对于比较繁忙的系统,每天产生大量日志,这些日志如果长时间不清除,将会对磁盘空间带来极大的浪费,因此,需要定期删除日志

删除所有日志

执行 reset master; 命令将删除所有 binlog 日志,新日志编号从“000001”开始

删除指定序号之前的日志文件

执行purge master logs to 'mysql-bin.'命令,将删除编号之前的所有日志(不删除命令中指定的文件)

删除指定日期前的日志

执行purge master log before 'yyyy-mm-dd hh24:mi:ss' 命令将删除指定日期前的所有日志

修改配置文件,自动删除

在配置文件的[mysqld]中设置参数 expire_logs_days=#, 此参数的含义是设置日志的过期天数,过了指定的天数后日志将会被自动删除。

3. 配置

–binlog-do-db=db_name

该选项告诉主服务器,如果当前的数据库(即 use 选定的数据库)是 db_name, 应将更新记录到二进制文件中,其他所有么有显式指定的数据库更新将被忽略,不记录在日志中。

–binlog-ignore-db=db_name

该选项告诉主服务器,如果当前的数据库(即 use 选定的数据库) 是 db_name,不应将更新保存到二进制日志中,其他没有显式忽略的数据库都将进行记录。
如果想记录或忽略多个数据库,可以对上面两个选项分别使用多次。

–innodb-safe-binlog

此选项经常和 –sync-binlog = N (每写 N 次日志同步磁盘)一起配合使用,使得事务在日志中的记录更加安全。

Edgar

Edgar
一个略懂Java的小菜比