Mysql二进制日志详解

引言

Mysql二进制日志详解_第1张图片 注:图片取自网络

提一下比较重要的几个:

重做日志(Redo Log):重做日志是实现mysql事务的持久性的原理之一,当新增数据时,Redo Log会备份新数据,在事务提交前,只要持久化Redo Log即可,而不需要持久化实际数据,如果这时候mysql系统崩溃,虽然数据还没有持久化新增数据,但是Redo Log已经持久化了,系统可以根据Redo Log内容将数据恢复到最新的状态。

回滚日志(Undo Log):回滚日志是实现mysql事务的原子性和一致性的原理之一,在操作任何数据之前,会先将数据备份到某个地方(这个存储数据备份的地方称为Undo Log),然后进行数据的修改,当修改发生错误或用户执行了Rollback回滚操作,系统就会根据Undo Log恢复到事务执行之前的状态。

二进制日志(binlog):MySQL的二进制日志是MySQL服务层的日志之一。其记录了所有对MySQL数据库的CRUD事件,包括增删改查和对表的系列操作记录,其记录的日志都是经过comomit的操作,对于失败、回滚或未提交的操作不会记录。通过mysql的二进制日志增量,可以较好到的实现mysql的复制和备份。

慢查日志(slow_query_log):参考我的这篇文章https://blog.csdn.net/fanrenxiang/article/details/83687241

中继日志(relay_log):这个日志暂时还没怎么研究过,只知道在mysql主从复制时候用到了,从服务器上会将二进制日志写入relay_log,然后从服务器再重放relay_log来实现mysql复制功能。

三种二进制日志格式

statement:基于SQL语句的形式,采用这种格式的话,你的二进制日志文件里记录的就是你执行的SQL语句,例如你执行的是delete from table where id<100;那记录的就是该条SQL,个人觉得记录的比较"粗糙";

row:行格式记录二进制日志,记录的是SQL对应的每一行的操作,粒度比statement细,也是推荐的格式;

mixed:混合格式,由mysql自己决定什么时候用row,什么时候用statement;

mysql> show variables like '%log_bin%';    #查看二进制相关信息
+---------------------------------+---------------------------------------+
| Variable_name                   | Value                                 |
+---------------------------------+---------------------------------------+
| log_bin                         | ON                                    |
| log_bin_basename                | /usr/local/mysql/data/mysql-bin       |
| log_bin_index                   | /usr/local/mysql/data/mysql-bin.index |
| log_bin_trust_function_creators | OFF                                   |
| log_bin_use_v1_row_events       | OFF                                   |
| sql_log_bin                     | ON                                    |
+---------------------------------+---------------------------------------+
6 rows in set (0.01 sec)

mysql> show variables like '%binlog_format%';    #查看二进制日志格式
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set (0.00 sec)

二进制日志若未开启,在 /etc/my.cnf 中的[mysqld]下面加上即可开启

[mysqld]
log-bin=/logs/mysql-bin         ##二进制日志存放位置
binlog_format=statement         ##二进制日志格式

或者执行如下命令即可

mysql> set global binlog_format=MIXED;

如果你没显式的配置二进制日志的目录位置,默认在${mysql安装目录}/data/下。 

二进制日志格式对比

binlog_format=statement 日志记录量较小,节约磁盘空间和网络IO 非确定行函数复制可能失败,主从复制存在不一致风险
binlog_format=row 避免主从复制不一致问题,复制效率高于statement 日志记录量大于statement,自然就消耗多一些的磁盘和IO
binlog_format=mixed 根据sql语句由系统决定使用row还是statement格式  

可以使用下面语句修改日志格式:

mysql>set global binlog_format=row;

当binlog_format=statement时数据库进行批量操作时,如update tablename set column1=‘foo’ where id>2,则statement格式只记录此条sql,而row格式则会记录每一行的修改操作。

mysql 5.7版本开始,其二进制日志格式默认为row。其中,row格式中细化的binlog_row_image属性又可设置为FULL、MINIMAL、NOBLOB 类型,这里推荐使用binlog_row_img=MINIMAL。

mysql> show variables like 'binlog_row_image';  //查询row格式
mysql> set global binlog_row_image=minimal;    //设置row格式

如何选择mysql的二进制日志格式

推荐使用binlog_format=mixed,若复制操作走的是内网操作,则可以选择row格式来确保主从复制一致性,同时选择binlog_row_image=minial格式来减少磁盘占用和网络IO。

binlog_format=statement还是binlog_format=row决定了复制方式是基于sql语句的复制还是基于行的复制,其优缺点大致参考这两种日志格式对应的优缺点。

二进制日志的记录时机

二进制日志文件的记录可以是同步或者异步,写入时机在mysql事务提交之后,主要由sync_binlog参数决定,当sync_binlog=1表示最高安全级别的写入(最大程度的保证事务不丢失)

mysql> show variables like '%sync_binlog%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sync_binlog   | 1     |
+---------------+-------+
1 row in set (0.01 sec)

二进制日志的文件大小

单个二进制日志文件的大小限制,可以通过以下命令查看

mysql> show variables like 'max_binlog_size';
+-----------------+------------+
| Variable_name   | Value      |
+-----------------+------------+
| max_binlog_size | 1073741824 |
+-----------------+------------+
1 row in set (0.01 sec)

如果超过了这个限制,则会自动滚动清理,也就是由之前的mysql-bin.000001变为mysql-bin.000002。

通过show master logs;命令来查看当前二进制日志文件数。

二进制日志文件的滚动清理

上面说到,超过限制大小后会自动生成新的二进制日志文件,这里说的是这些日志文件的删除

mysql> show variables like 'expire_logs_days';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| expire_logs_days | 0     |
+------------------+-------+
1 row in set (0.01 sec)

如上是0,表示不过期,如果我设置为2,表示超过两天的二进制日志会被自动删除。

也可以手动 flush logs;来显式的进行二进制日志文件的滚动清理。

引申文章:

Mysql主从复制-基于GTID复制(https://blog.csdn.net/fanrenxiang/article/details/70197004)

Mysql主从复制-基于日志点复制(https://blog.csdn.net/fanrenxiang/article/details/70194707)

你可能感兴趣的:(数据库,Mysql)