
如果英文不好的话,可以参考 searchdoc 翻译的中文版本
http://www.searchdoc.cn/rdbms/mysql/dev.mysql.com/doc/refman/5.7/en/index.com.coder114.cn.html

二进制日志 : http://www.searchdoc.cn/rdbms/mysql/dev.mysql.com/doc/refman/5.7/en/binary-log.com.coder114.cn.html
以Innodb存储引擎来讲,主要由 Redo log 和 Undo log , 为了支持事务。
这里我们重点来了解下 binlog的主要功能
binlog中主要记录了所有对MySQL数据库的修改事件,包括增删改事件以及对表结构的修改事件,不包括 select 和 show 之类的操作(这部分会记到查询日志中) 。 需要注意的一点: 只有成功执行的才回被记录到binlog中,那些执行出错或者已经回滚的数据,是不会被记录到binlog中的。
binlog 的主要目的是主从复制和数据恢复
InnoDB (支持事务的存储引擎),必须要提交了事务才会记录binlog。binlog 什么时候刷新到磁盘取决于参数 sync_binlog
如果 sync_binlog=0 或 sync_binlog大于1,当发生电源故障或操作系统崩溃时,可能有一部分已提交但其binlog未被同步到磁盘的事务会被丢失,恢复程序将无法恢复这部分事务。
建议设置为1是最安全的,在系统故障时最多丢失一个事务的更新,但是会对性能有所影响。
binlog日志包括两类文件:
以上三种情况,MySQL会重新生成一个新的日志文件,文件序号递增。
注: max_binlog_size 的最小值是4096字节,最大值和默认值是 1GB (1073741824字节)。
事务被写入到binlog的一个块中,所以它不会在几个二进制日志之间被拆分。因此,如果你有很大的事务,为了保证事务的完整性,不可能做切换日志的动作,只能将该事务的日志都记录到当前日志文件中,直到事务结束,所以有的时候我们会看到binlog文件大于 max_binlog_size 的情况。
二进制日志中的事件的格式取决于二进制记录格式。支持三种格式类型:
Version < MySQL 5.7.7 ,默认的格式是 STATEMENT,
Version >= MySQL 5.7.7 + ,默认值是 ROW。
日志格式通过 binlog-format 指定 —> binlog-format=STATEMENT、binlog-format=ROW、binlog-format=MIXED。
基于段的格式 binlog_format=STATEMENT
[root@artisan ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 44
Server version: 5.7.29-log MySQL Community Server (GPL)
.....
.....
mysql> show variables like 'binlog_format'; # 查看当前binlog的格式
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.00 sec)
mysql> set session binlog_formate=statement; # 修改session级别的binlog格式为statement
mysql> set session binlog_format=statement;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'binlog_format'; #确认下当前binlog的格式
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| binlog_format | STATEMENT |
+---------------+-----------+
1 row in set (0.00 sec)
mysql> show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 177 |
| mysql-bin.000002 | 177 |
....
....
| mysql-bin.000049 | 177 |
+------------------+-----------+
45 rows in set (0.00 sec)
mysql> flush logs; # 刷新log ,会产生一个新的binlog
Query OK, 0 rows affected (0.05 sec)
mysql> show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 177 |
....
....
| mysql-bin.000049 | 177 |
| mysql-bin.000050 | 154 |
+------------------+-----------+
46 rows in set (0.00 sec)
mysql> 下面随便搞点操作,方便观察binlog
mysql> create database artisan2;
Query OK, 1 row affected (0.00 sec)
mysql> use artisan2;
Database changed
mysql> create table t(id int , c1 varchar(10));
Query OK, 0 rows affected (0.30 sec)
mysql> insert into t values(1,'a'),(2,'b');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> 切到binlog的目录下 (/etc/my.cnf中配置的log-bin项)

[root@artisan binlog]# pwd
/var/lib/mysql/data/binlog
[root@artisan binlog]# mysqlbinlog mysql-bin.000050
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#200131 16:15:14 server id 1 end_log_pos 123 CRC32 0xf1d6a9f8 Start: binlog v 4, server v 5.7.29-log created 200131 16:15:14
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
EuIzXg8BAAAAdwAAAHsAAAABAAQANS43LjI5LWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
Afip1vE=
'/*!*/;
# at 123
#200131 16:15:14 server id 1 end_log_pos 154 CRC32 0x19c20618 Previous-GTIDs
# [empty]
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@artisan binlog]# 5.7.29版本的这个statement格式的binlog ,居然没法直接看内容了 ,先记录下。
5.7.9中 还能看到具体的SQL

基于行的日志格式 binlog_format=ROW
举个例子,假设有一个SQL修改了1万条数据, 基于段Statement的日志格式仅仅会记录这个SQL, 而基于Row的日志会有1万条记录分别记录每一行的数据修改。
binlog_row_image = FULL | MINIMAL | NOBLOB (3个选项,默认FULL)举个例子 一个表中 有 20 列(20个字段) ,3个参数的区别如下
mysql> show variables like 'binlog_row_image';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| binlog_row_image | FULL |
+------------------+-------+
1 row in set (0.00 sec)
mysql> set session binlog_row_image=minimal; # 修改
Query OK, 0 rows affected (0.00 sec)增加c2字段 ,text类型

默认 FULL的情况
mysqlbinlog -vv 命令查看ROW格式的日志

修改为 minimal

mysqlbinlog -vv 命令查看ROW格式的日志

可以看到

仅记录了 变化的 字段的内容。
设置参数为 noblob

将非 blob字段 更新下,看看是否记录blob字段的信息

mysqlbinlog -vv 命令查看ROW格式的日志

可以看到

第三列,text类型的,并没有在binLog中。
Row格式的 增加 -vv 查看
[root@artisan binlog]# mysqlbinlog -vv mysql-bin.000050我这个5.7.29的版本 看不到。。。有可能是打开方式不对,待确认 。
5.7.9版本可以
binlog_format=MIXED不展开了,并不是一种新的格式
## binlog相关的命令
```sql
# 查看是否开启binlog
mysql>show binary logs;
#查看binlog格式:
mysql>show variables like 'binlog_format';
#获取binlog文件列表:
mysql>show binary logs;
#查看当前正在写入的binlog文件:
mysql>show master status;
#查看master上的binlog:
mysql>show master logs;
#只查看第一个binlog文件的内容:
mysql>show binlog events;
#查看指定binlog文件的内容:
mysql>show binlog events in 'mysql-bin.000045';
#清空所有的bin-log:
mysql>reset master;
#生成一个新的binlog:
mysql>flush logs;
建议 binlog_format=mixed 或者 row, 如果用row的话,最好binlog_row_image=minimal ,减少binlog的大小,占用更少的网络I/O 和 磁盘I/O