Mysql数据库的日志可以分为服务层和存储引擎层日志。服务层日志主要包含二进制日志(binlog)、慢查询日志和通用日志;存储引擎层日志(以InnoDB为例)包含重做日志(redolog)和回滚日志(undolog)。
binlog中只存储执行成功的日志。
binlog的三种格式
设置binlog日志格式的参数:
set binlog_format=[statement|row|mixed];
查看binlog文件:
show binary logs;
刷新log文件:
flush logs;
查看binlog内容:
mysqlbinlog -vv binlog.000154
一、STATEMENT
按段存储,mysql 5.7 之前的版本默认使用的日志格式。binlog中只记录数据库修改时使用的sql语句。
优点:
日志较小,节省磁盘和网络IO,只记录sql语句
缺点:
必须记录上下文信息,以保证在从服务器上能得到相同的结果
特定函数无法复制,如UUID(), user(),可能造成主从服务器数据不一致
BEGIN
/*!*/;
# at 1351
# at 1383
#210216 23:44:22 server id 1 end_log_pos 1383 CRC32 0x3a8b5df0 Intvar
SET INSERT_ID=3/*!*/;
#210216 23:44:22 server id 1 end_log_pos 1492 CRC32 0x2503c540 Query thread_id=15 exec_time=0 error_code=0
SET TIMESTAMP=1613490262/*!*/;
/*!80013 SET @@session.sql_require_primary_key=0*//*!*/;
insert into t (num) values (3)
/*!*/;
# at 1492
#210216 23:44:22 server id 1 end_log_pos 1523 CRC32 0xe14ff0b0 Xid = 297
COMMIT/*!*/;
二、ROW
基于行的binlog日志格式,Mysql 5.7 版本之后默认的binlog日志格式
优点:
主从复制更加安全
对每一行的复制效率高于基于段的复制效率
如果对数据进行了误操作,可以通过ROW格式的binlog进行反向处理,恢复数据
缺点:
记录的日志量较大,尤其是对于批量处理数据,每一行变动都会记录
优化:
mysql通过binlog_row_image
参数对ROW格式的binlog进行了优化
set binlog_row_image=[FULL|MANIMAL|NOBLOG]
**FULL:**默认,记录被修改行的数据的所有列的内容
### UPDATE `test`.`t` ### WHERE ### @1=4 /* INT meta=0 nullable=0 is_null=0 */ ### @2=4 /* INT meta=0 nullable=1 is_null=0 */ ### SET ### @1=4 /* INT meta=0 nullable=0 is_null=0 */ ### @2=5 /* INT meta=0 nullable=1 is_null=0 */
**MINIMAL:**只记录被修改的列的变化
### UPDATE `test`.`t` ### WHERE ### @1=4 /* INT meta=0 nullable=0 is_null=0 */ ### SET ### @2=4 /* INT meta=0 nullable=1 is_null=0 */ # at 1035 #210217 0:14:33 server id 1 end_log_pos 1066 CRC32 0x37eac0bb Xid = 309 COMMIT/*!*/;
**NOBLOG:**与FULL类似,但是对于blog和text的值没有修改的话,就不记录(这里我先在表中添加了一个text字段)
### UPDATE `test`.`t` ### WHERE ### @1=3 /* INT meta=0 nullable=0 is_null=0 */ ### @2=3 /* INT meta=0 nullable=1 is_null=0 */ ### SET ### @1=3 /* INT meta=0 nullable=0 is_null=0 */ ### @2=4 /* INT meta=0 nullable=1 is_null=0 */ # at 1522 #210217 0:22:11 server id 1 end_log_pos 1553 CRC32 0x853a53a6 Xid = 315 COMMIT/*!*/;
上面的日志中省略了text字段:
mysql> select * from t; +----+------+------+ | id | num | tt | +----+------+------+ | 1 | 1 | NULL | | 3 | 4 | NULL | +----+------+------+
三、MIXED
mixed 格式由系统来决定使用哪种格式
- 系统根据sql语句来决定使用STATEMENT还是ROW。一般使用statement,如果sql中含有不确定函数,则会使用row格式
- 日志的大小由sql和事务的隔离级别来决定。如果隔离级别设置为读已提交,则会使用row格式
binlog日志格式对复制的影响
基于sql语句的复制(SBR)
主库binlog采用statement格式的时候。
优点:
日志量比较少,节约网络IO
不强制要求主从数据库的表定义完全相同(列的顺序可以不同)。
复制方式更加灵活
缺点:
无法保证非缺点函数的结果,如UUID()
对存储过程、触发器、自定义函数进行修改可能导致数据不一致
可能需要锁定更多的行
基于行的复制(RBR)
主库binlog采用row格式的时候。
优点:
能够保证主从库的数据一致
可以减少从服务器上行锁的使用
缺点:
要求主从服务器上的表结构完全一致,否则可能会中断复制
无法在从服务器上执行触发器