前言:binlog 用于记录数据库执行写入性操作的日志信息,以二进制的形式保留在磁盘中。它是由 Server 层进行记录的,使用任何存储引擎都会产生 binlog。

实验准备

我们通过 Docker 来对 MySQL binlog 进行一系列的研究。需要进行一些准备工作:

  1. 拉取 mysql 5.7 版本镜像
$ docker pull mysql:5.7
  1. 准备 mysql 容器挂载的目录,以及配置文件信息
$ mkdir -p infra/mysql
$ cd infra/mysql
# 挂载目录
$ mkdir data
# 配置文件
$ mkdir mysql.conf.d && cd mysql.conf.d
$ echo "[mysqld]
# 设置binlog的格式
binlog_format = statement
# 设置日志存储路径
log-bin=/var/lib/mysql/mysql-bin
server-id=12345" > mysqld.cnf
  1. 启动 mysql 容器,查看 bin_log 是否开启
# 启动容器
$ docker run -p3306:3306 -d --name mysql57 \
-v /Users/zioyi/infra/mysql/mysql.conf.d:/etc/mysql/conf.d \
-v /Users/zioyi/infra/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root --restart=always mysql:5.6
# 进入容器
$ docker exec -it mysql57 sh
$ [mysql57] mysql -uroot -proot
mysql > show variable like "%log_bin%";
+---------------------------------+--------------------------------+
| Variable_name | Value |
+---------------------------------+--------------------------------+
| log_bin | ON |
| log_bin_basename | /var/lib/mysql/mysql-bin |
| log_bin_index | /var/lib/mysql/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.00 sec)
  1. 创建数据库和表
mysql > create database mall character set utf8mb4 collate utf8mb4_unicode_ci;
Query OK, 1 row affected (0.01 sec) mysql > use mall;
Database changed
mysql > CREATE TABLE `item` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT '' COMMENT '商品名称',
`price` int(10) unsigned DEFAULT '0' COMMENT '价格',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品清单';

binlog 的三种格式

STATMENT

基于 SQL 语句的复制(statment-based replication,SBR),每一条会修改数据的 SQL 语句都会复制到 binlog 中。

我们将 bin_log 的模式设置成 STATMENT,之后重启容器

$ echo "[mysqld]
# 设置binlog的格式
binlog_format = statement
# 设置日志存储路径
log-bin=/var/lib/mysql/mysql-bin
server-id=12345" > mysqld.cnf

在数据库中插入一条数据

mysql> insert into item(name, price) values("book", 10);
Query OK, 1 row affected (0.01 sec) # 知道最新的 binlog 文件进行查看
show binlog events in 'mysql-bin.000004';
+------------------+-----+-------------+-----------+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mysql-bin.000004 | 4 | Format_desc | 12345 | 120 | Server ver: 5.6.51-log, Binlog ver: 4 |
| mysql-bin.000004 | 120 | Query | 12345 | 263 | create database mall character set utf8mb4 collate utf8mb4_unicode_ci |
| mysql-bin.000004 | 263 | Query | 12345 | 446 | create database blog_service default character set utf8mb4 default collate utf8mb4_general_ci |
| mysql-bin.000004 | 446 | Query | 12345 | 758 | use `mall`; CREATE TABLE `item` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT '' COMMENT '',
`price` int(10) unsigned DEFAULT '0' COMMENT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='' |
| mysql-bin.000004 | 758 | Query | 12345 | 837 | BEGIN |
| mysql-bin.000004 | 837 | Intvar | 12345 | 869 | INSERT_ID=1 |
| mysql-bin.000004 | 869 | Query | 12345 | 991 | use `mall`; insert into item(name, price) values("book", 10) |
| mysql-bin.000004 | 991 | Xid | 12345 | 1022 | COMMIT /* xid=15 */ |
+------------------+-----+-------------+-----------+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

可以看到,我们的插入已经被记录,我们再往表中多插入几条数据:

mysql > insert into item(name, price) values("fruit", 12);
mysql > insert into item(name, price) values("rice", 2);
# 向表中加入要给新字段
mysql > alter table item add column type smallint default 0;
mysql > update item set type = 1 where type = 0;
# 在看一下binlog中
mysql > show binlog events in 'mysql-bin.000004';
| mysql-bin.000004 | 1022 | Query | 12345 | 1101 | BEGIN |
| mysql-bin.000004 | 1101 | Intvar | 12345 | 1133 | INSERT_ID=2 |
| mysql-bin.000004 | 1133 | Query | 12345 | 1256 | use `mall`; insert into item(name, price) values("fruit", 12) |
| mysql-bin.000004 | 1256 | Xid | 12345 | 1287 | COMMIT /* xid=23 */ |
| mysql-bin.000004 | 1287 | Query | 12345 | 1366 | BEGIN |
| mysql-bin.000004 | 1366 | Intvar | 12345 | 1398 | INSERT_ID=3 |
| mysql-bin.000004 | 1398 | Query | 12345 | 1519 | use `mall`; insert into item(name, price) values("rice", 2) |
| mysql-bin.000004 | 1519 | Xid | 12345 | 1550 | COMMIT /* xid=25 */ |
| mysql-bin.000004 | 1550 | Query | 12345 | 1675 | use `mall`; alter table item add column type smallint default 0 |
| mysql-bin.000004 | 1675 | Query | 12345 | 1754 | BEGIN |
| mysql-bin.000004 | 1754 | Query | 12345 | 1867 | use `mall`; update item set type = 1 where type = 0 |
| mysql-bin.000004 | 1867 | Xid | 12345 | 1898 | COMMIT /* xid=31 */ |

可以看到,insertalertupdate等 SQL 语句都会被记录在 binlog 中,并且都和执行时的语句一模一样。

总结一下 STATEMENT 这种方式的优缺点:

  • 优点:如果是 alter、update 这种会影响修改多行记录的变更,只需要记录一行 SQL 就行(相比于 ROW 模式),这样减少了 binlog 的日志量,节约了 IO,从而提高了性能。
  • q

ROW

基于行的复制(row-based repication,RBR),不记录每天 SQL 语句的上下文信息,仅需记录哪条语句被修改了。

更改 binlog 的模式为 ROW:

mysql > set global binlog_format = ROW;
mysql > select @@global.binlog_format;
+------------------------+
| @@global.binlog_format |
+------------------------+
| ROW |
+------------------------+
1 row in set (0.00 sec) # 更新
mysql > update item set type = 1 where type = 2;
Query OK, 3 rows affected (0.01 sec)
Rows matched: 3 Changed: 3 Warnings: 0

对于 STATEMENT 格式的 binlog ,所有的 DML 操作都记录在 QUERY_EVENT 中,所以我们直接通过show binlog events in 'mysql-bin.000004';就可以看到;

而对于 ROW 格式的 binlog ,所有的 DML 操作都记录在 ROWS_EVENT 中,ROWS_EVENT 分为三种:WRITE_ROWS_EVENT,UPDATE_ROWS_EVENT,DELETE_ROWS_EVENT,分别对应 insert,update 和 delete 操作。我们需要通过 mysqlbinlog 工具来查看

来查看一下 ROW 内容:

$ mysqlbinlog mysql-bin.000004 -vv --base64-output=decode-rows
#211219 15:07:12 server id 12345 end_log_pos 2162 CRC32 0xb0fc9915 Update_rows: table id 73 flags: STMT_END_F
### UPDATE `mall`.`item`
### WHERE
### @1=1 /* INT meta=0 nullable=0 is_null=0 */
### @2='book' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=10 /* INT meta=0 nullable=1 is_null=0 */
### @4=1 /* SHORTINT meta=0 nullable=1 is_null=0 */
### SET
### @1=1 /* INT meta=0 nullable=0 is_null=0 */
### @2='book' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=10 /* INT meta=0 nullable=1 is_null=0 */
### @4=2 /* SHORTINT meta=0 nullable=1 is_null=0 */
### UPDATE `mall`.`item`
### WHERE
### @1=2 /* INT meta=0 nullable=0 is_null=0 */
### @2='fruit' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=12 /* INT meta=0 nullable=1 is_null=0 */
### @4=1 /* SHORTINT meta=0 nullable=1 is_null=0 */
### SET
### @1=2 /* INT meta=0 nullable=0 is_null=0 */
### @2='fruit' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=12 /* INT meta=0 nullable=1 is_null=0 */
### @4=2 /* SHORTINT meta=0 nullable=1 is_null=0 */
### UPDATE `mall`.`item`
### WHERE
### @1=3 /* INT meta=0 nullable=0 is_null=0 */
### @2='rice' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=2 /* INT meta=0 nullable=1 is_null=0 */
### @4=1 /* SHORTINT meta=0 nullable=1 is_null=0 */
### SET
### @1=3 /* INT meta=0 nullable=0 is_null=0 */
### @2='rice' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=2 /* INT meta=0 nullable=1 is_null=0 */
### @4=2 /* SHORTINT meta=0 nullable=1 is_null=0 */
# at 2162
#211219 15:07:12 server id 12345 end_log_pos 2193 CRC32 0x44ee46b2 Xid = 44
COMMIT/*!*/;
DELIMITER ;

在 ROW 模式中,将update item set type = 1 where type = 2;语句记录成了对 3 条记录的变更操作,分别是对于每条满足 where 条件的记录的独立 update 语句。

delete 语句也是一样

mysql> update item set type = 1 where id = 3;
Query OK, 1 row affected (0.04 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from item ;
+----+-------+-------+------+
| id | name | price | type |
+----+-------+-------+------+
| 1 | book | 10 | 2 |
| 2 | fruit | 12 | 2 |
| 3 | rice | 2 | 1 |
+----+-------+-------+------+
3 rows in set (0.00 sec) mysql> delete from item where type = 2;
Query OK, 2 rows affected (0.01 sec)
$ mysqlbinlog mysql-bin.000004 -vv --base64-output=decode-rows
### DELETE FROM `mall`.`item`
### WHERE
### @1=1 /* INT meta=0 nullable=0 is_null=0 */
### @2='book' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=10 /* INT meta=0 nullable=1 is_null=0 */
### @4=2 /* SHORTINT meta=0 nullable=1 is_null=0 */
### DELETE FROM `mall`.`item`
### WHERE
### @1=2 /* INT meta=0 nullable=0 is_null=0 */
### @2='fruit' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=12 /* INT meta=0 nullable=1 is_null=0 */
### @4=2 /* SHORTINT meta=0 nullable=1 is_null=0 */
# at 2612
#211220 1:18:03 server id 12345 end_log_pos 2643 CRC32 0x435b7a4b Xid = 55
COMMIT/*!*/;

再看一下 alter 语句

mysql> alter table item add column updated datetime default CURRENT_TIMESTAMP;
mysqlbinlog mysql-bin.000004 -vv --base64-output=decode-rows
# at 2612
#211220 1:18:03 server id 12345 end_log_pos 2643 CRC32 0x435b7a4b Xid = 55
COMMIT/*!*/;
# at 2643
#211220 1:24:43 server id 12345 end_log_pos 2795 CRC32 0x68a196c8 Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1639963483/*!*/;
SET @@session.time_zone='SYSTEM'/*!*/;
alter table item add column updated datetime default CURRENT_TIMESTAMP
/*!*/;

binlog 中记录了当前的时间戳 1639963483。

再看一下使用系统函数的语句

mysql> select sysdate();
+---------------------+
| sysdate() |
+---------------------+
| 2021-12-20 01:31:26 |
+---------------------+
1 row in set (0.00 sec) mysql> update item set updated = sysdate() where id = 3;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from item;
+----+------+-------+------+---------------------+
| id | name | price | type | updated |
+----+------+-------+------+---------------------+
| 3 | rice | 2 | 1 | 2021-12-20 01:32:15 |
+----+------+-------+------+---------------------+
1 row in set (0.00 sec)
$ mysqlbinlog mysql-bin.000004 -vv --base64-output=decode-rows
# at 2875
#211220 1:32:15 server id 12345 end_log_pos 2929 CRC32 0x1f777374 Table_map: `mall`.`item` mapped to number 74
# at 2929
#211220 1:32:15 server id 12345 end_log_pos 3009 CRC32 0x312870a3 Update_rows: table id 74 flags: STMT_END_F
### UPDATE `mall`.`item`
### WHERE
### @1=3 /* INT meta=0 nullable=0 is_null=0 */
### @2='rice' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=2 /* INT meta=0 nullable=1 is_null=0 */
### @4=1 /* SHORTINT meta=0 nullable=1 is_null=0 */
### @5='2021-12-20 01:24:43' /* DATETIME(0) meta=0 nullable=1 is_null=0 */
### SET
### @1=3 /* INT meta=0 nullable=0 is_null=0 */
### @2='rice' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=2 /* INT meta=0 nullable=1 is_null=0 */
### @4=1 /* SHORTINT meta=0 nullable=1 is_null=0 */
### @5='2021-12-20 01:32:15' /* DATETIME(0) meta=0 nullable=1 is_null=0 */
# at 3009
#211220 1:32:15 server id 12345 end_log_pos 3040 CRC32 0xb49295bc Xid = 59
COMMIT/*!*/;

在 binlog 中,会直接把 sysdate() 当时返回的值记录在 update 语句中。

MIXED

基于 STATMENT 和 ROW 两种模式的混合复制(mixed-based replication,MBR),一般的复制使用 STATMENT 模式保存 binlog,对于 STATEMENT 模式无法复制的操作使用 ROW 模式保存 binlog。

mysql > set global binlog_format = MIXED;
mysql > select @@global.binlog_format;
+------------------------+
| @@global.binlog_format |
+------------------------+
| ROW |
+------------------------+
1 row in set (0.00 sec) # 更新
mysql > update item set type = 1 where type = 2;
Query OK, 3 rows affected (0.01 sec)
Rows matched: 3 Changed: 3 Warnings: 0

插入语句1

mysql> insert into item(name, price, type) values("pencil", 1, 3);
Query OK, 1 row affected (0.00 sec)
$ mysqlbinlog mysql-bin.000004 -vv --base64-output=decode-rows
#211220 1:39:45 server id 12345 end_log_pos 3233 CRC32 0xfcb23be0 Write_rows: table id 74 flags: STMT_END_F
### INSERT INTO `mall`.`item`
### SET
### @1=4 /* INT meta=0 nullable=0 is_null=0 */
### @2='pencil' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=1 /* INT meta=0 nullable=1 is_null=0 */
### @4=3 /* SHORTINT meta=0 nullable=1 is_null=0 */
### @5='2021-12-20 01:39:45' /* DATETIME(0) meta=0 nullable=1 is_null=0 */
# at 3233
#211220 1:39:45 server id 12345 end_log_pos 3264 CRC32 0x1ee1856c Xid = 62
COMMIT/*!*/;

通过 ROW 模式记录,因为 updated 字段是通过 current_timestamp 来得到的

update 语句1

mysql> update item set type = 4;
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0
$ mysqlbinlog mysql-bin.000004 -vv --base64-output=decode-rows
### UPDATE `mall`.`item`
### WHERE
### @1=3 /* INT meta=0 nullable=0 is_null=0 */
### @2='rice' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=2 /* INT meta=0 nullable=1 is_null=0 */
### @4=1 /* SHORTINT meta=0 nullable=1 is_null=0 */
### @5='2021-12-20 01:32:15' /* DATETIME(0) meta=0 nullable=1 is_null=0 */
### SET
### @1=3 /* INT meta=0 nullable=0 is_null=0 */
### @2='rice' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=2 /* INT meta=0 nullable=1 is_null=0 */
### @4=4 /* SHORTINT meta=0 nullable=1 is_null=0 */
### @5='2021-12-20 01:32:15' /* DATETIME(0) meta=0 nullable=1 is_null=0 */
### UPDATE `mall`.`item`
### WHERE
### @1=4 /* INT meta=0 nullable=0 is_null=0 */
### @2='pencil' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=1 /* INT meta=0 nullable=1 is_null=0 */
### @4=3 /* SHORTINT meta=0 nullable=1 is_null=0 */
### @5='2021-12-20 01:39:45' /* DATETIME(0) meta=0 nullable=1 is_null=0 */
### SET
### @1=4 /* INT meta=0 nullable=0 is_null=0 */
### @2='pencil' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=1 /* INT meta=0 nullable=1 is_null=0 */
### @4=4 /* SHORTINT meta=0 nullable=1 is_null=0 */
### @5='2021-12-20 01:39:45' /* DATETIME(0) meta=0 nullable=1 is_null=0 */
### UPDATE `mall`.`item`
### WHERE
### @1=5 /* INT meta=0 nullable=0 is_null=0 */
### @2='pencil' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=1 /* INT meta=0 nullable=1 is_null=0 */
### @4=3 /* SHORTINT meta=0 nullable=1 is_null=0 */
### @5='2021-12-20 10:00:00' /* DATETIME(0) meta=0 nullable=1 is_null=0 */
### SET
### @1=5 /* INT meta=0 nullable=0 is_null=0 */
### @2='pencil' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=1 /* INT meta=0 nullable=1 is_null=0 */
### @4=4 /* SHORTINT meta=0 nullable=1 is_null=0 */
### @5='2021-12-20 10:00:00' /* DATETIME(0) meta=0 nullable=1 is_null=0 */
# at 3782

还是使用 ROW 模式,看来只要表中有default current_timestamp字段,都是这样的。

我们把 updated 字段删掉,再来更新试试:

mysql> alter table item drop column updated;
Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0 mysql> select * from item;
+----+--------+-------+------+
| id | name | price | type |
+----+--------+-------+------+
| 3 | rice | 2 | 4 |
| 4 | pencil | 1 | 4 |
| 5 | pencil | 1 | 4 |
+----+--------+-------+------+
3 rows in set (0.00 sec) mysql> update item set type = 5;
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> show binlog events in 'mysql-bin.000004';
| mysql-bin.000004 | 3813 | Query | 12345 | 3923 | use `mall`; alter table item drop column updated |
| mysql-bin.000004 | 3923 | Query | 12345 | 4002 | BEGIN |
| mysql-bin.000004 | 4002 | Query | 12345 | 4100 | use `mall`; update item set type = 5 |
| mysql-bin.000004 | 4100 | Xid | 12345 | 4131 | COMMIT /* xid=82 */ |

此时就是使用 STATMENT 模式来存储 binlog了。

如果使用系统函数呢

mysql> update item set type = ceil(rand() * 10);
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0 mysql> select * from item;
+----+--------+-------+------+
| id | name | price | type |
+----+--------+-------+------+
| 3 | rice | 2 | 4 |
| 4 | pencil | 1 | 10 |
| 5 | pencil | 1 | 8 |
+----+--------+-------+------+
3 rows in set (0.00 sec)

每行的 type 都不一样,看起来这只能通过 ROW 模式来就记录了吧?来看看 binlog

$ mysqlbinlog mysql-bin.000004 -vv --base64-output=decode-rows
#211220 1:57:57 server id 12345 end_log_pos 4401 CRC32 0x95bf290e Update_rows: table id 75 flags: STMT_END_F
### UPDATE `mall`.`item`
### WHERE
### @1=3 /* INT meta=0 nullable=0 is_null=0 */
### @2='rice' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=2 /* INT meta=0 nullable=1 is_null=0 */
### @4=5 /* SHORTINT meta=0 nullable=1 is_null=0 */
### SET
### @1=3 /* INT meta=0 nullable=0 is_null=0 */
### @2='rice' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=2 /* INT meta=0 nullable=1 is_null=0 */
### @4=4 /* SHORTINT meta=0 nullable=1 is_null=0 */
### UPDATE `mall`.`item`
### WHERE
### @1=4 /* INT meta=0 nullable=0 is_null=0 */
### @2='pencil' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=1 /* INT meta=0 nullable=1 is_null=0 */
### @4=5 /* SHORTINT meta=0 nullable=1 is_null=0 */
### SET
### @1=4 /* INT meta=0 nullable=0 is_null=0 */
### @2='pencil' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=1 /* INT meta=0 nullable=1 is_null=0 */
### @4=10 /* SHORTINT meta=0 nullable=1 is_null=0 */
### UPDATE `mall`.`item`
### WHERE
### @1=5 /* INT meta=0 nullable=0 is_null=0 */
### @2='pencil' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=1 /* INT meta=0 nullable=1 is_null=0 */
### @4=5 /* SHORTINT meta=0 nullable=1 is_null=0 */
### SET
### @1=5 /* INT meta=0 nullable=0 is_null=0 */
### @2='pencil' /* VARSTRING(400) meta=400 nullable=1 is_null=0 */
### @3=1 /* INT meta=0 nullable=1 is_null=0 */
### @4=8 /* SHORTINT meta=0 nullable=1 is_null=0 */
# at 4401

果真如此。

对比

模式 优点 缺点
STATMENT 如果是 alter、update 这种会影响修改多行记录的变更,只需要记录一行 SQL 就行这样减少了 binlog 的日志量,节约了 IO,从而提高了性能。 在某些情况下,无法还原当时的数据,比如:使用系统函数 sysdate()、rand()等
ROW 不会出现某些特定的存储过程、function、trigger的调研和触发无法被正确复制的问题 会产生大量的日志,比如 update 影响函数较多时。
MIXED 综合了 STATMENT 和 ROW 的优缺点 -

在MySQL 5.7.7之前,默认的格式是STATEMENT,MySQL 5.7.7之后,默认值是ROW。

binlog 刷盘时机

对于 InnoDB 存储引擎而言,只有在事务提交时才会记录 binlog,此时记录还在内存中,那么 binlog 是什么时候刷到磁盘中的呢?MySQL 通过 sync_binlog 参数控制 binlog 的刷盘时机,取值范围是0-N:

  • 0:不去强制要求,由系统自行判断何时写入磁盘;
  • 1:每次 commit 的时候都要将 binlog 写入磁盘;
  • N:每 N 个事务,才会将binlog写入磁盘。

从上面可以看出,sync_binlog 最安全的是设置是 1,这也是 MySQL 5.7.7 之后版本的默认值。但是设置一个大一些的值可以提升数据库性能,因此实际情况下也可以将值适当调大,牺牲一定的一致性来获取更好的性能。

binlog 的使用场景

在实际应用中,binlog 的主要使用场景有:

  • 数据恢复:通过使用 mysqlbinlog 工具来恢复数据。
  • 主从复制:在 Master 端开启 binlog,然后将 binlog 发送到各个 Slave 端,Slave 端重放 binlog 从而达到主从数据一致。
  • 数据同步:与主从复制类似,当我们想同步 MySQL 的数据到适合做数据分析的其他数据库中时,也是通过消费 binlog 来实现的。

MySQL 的日志:binlog的更多相关文章

  1. 必须了解的mysql三大日志-binlog、redo log和undo log

    日志是 mysql 数据库的重要组成部分,记录着数据库运行期间各种状态信息.mysql日志主要包括错误日志.查询日志.慢查询日志.事务日志.二进制日志几大类.作为开发,我们重点需要关注的是二进制日志( ...

  2. MySQL二进制日志binlog简单使用

    MySQL数据库进行了哪些CUD操作,通过binlog二进制文件可以查看.binlog不仅可以记录CUD的操作(select操作不包括在内),还是主从备份的基础.主库的操作记录成binlog文件,定期 ...

  3. 小记---------maxwell 一个可以实时读取mysql二进制日志binlog,并生成JSON格式的消息,作为生产者发送给kafka,Redis,文件或其他平台的应用程序

    maxwell主要提供了下列功能     支持 SELECT * FROM table 的方式进行全量数据初始化     支持在主库发生failover后,自动回复binlog位置(GTID)     ...

  4. mysql dba系统学习(6)二进制日志binlog之二

    MySQL 5.5 中对于二进制日志 (binlog) 有 3 种不同的格式可选:Mixed,Statement,Row,默认格式是 Statement.总结一下这三种格式日志的优缺点.MySQL R ...

  5. Mysql数据库之Binlog日志使用总结

    binlog二进制日志对于mysql数据库的重要性有多大,在此就不多说了.下面根据本人的日常操作经历,并结合网上参考资料,对binlog日志使用做一梳理: 一.binlog日志介绍1)什么是binlo ...

  6. mysql备份和bin-log日志

    总结]:mysql备份和bin-log日志 备份数据: mysqldump -uroot -p123456 test -l -F '/tmp/test.sql' -l:读锁(只能读取,不能更新) -F ...

  7. mysql 开发进阶篇系列 39 mysql日志之二进制日志(binlog)

    一.概述 二进制日志(binlog)记录了所有的DDL(数据定义语言)语句和DML(数据操纵语言)语句,但是不包括数据查询语句, 语句以"事件"的形式保存,它描述了数据的更改过程, ...

  8. (转)Mysql数据库之Binlog日志使用总结

    使用mysqlbinlog提取二进制日志 原文:http://blog.csdn.net/leshami/article/details/41962243 MySQL binlog日志记录了MySQL ...

  9. mysql 正确清理binlog日志的两种方法

    前言: MySQL中的binlog日志记录了数据库中数据的变动,便于对数据的基于时间点和基于位置的恢复,但是binlog也会日渐增大,占用很大的磁盘空间,因此,要对binlog使用正确安全的方法清理掉 ...

  10. 脚本备份MySQL数据库和binlog日志

    用Mysqldump实现全库备份+binlog的数据还原 首先是为mysql做指定库文件的全库备份 vim mysqlbak.sh #!/bin/bash #定义数据库目录,要能找到mysqldump ...

随机推荐

  1. [bzoj1044]木棍分割

    第一个问题可以用贪心+二分解决第二个问题用f[i][j]表示i次分割后分割到j且满足条件的方案数,$f[i][j]=\sum_{k<j且sum[j]-sum[k]<=ans}f[i-1][ ...

  2. 第03章_基本的SELECT语句

    第03章_基本的SELECT语句 1. SQL概述 1.1 SQL背景知识 1946 年,世界上第一台电脑诞生,如今,借由这台电脑发展起来的互联网已经自成江湖.在这几十年里,无数的技术.产业在这片江湖 ...

  3. App 端自动化的最佳方案,完全解放双手!

    1. 前言 大家好,我是安果! 之前写过一篇文章,文中提出了一种方案,可以实现每天自动给微信群群发新闻早报 如何利用 Python 爬虫实现给微信群发新闻早报?(详细) 但是对于很多人来说,首先编写一 ...

  4. CF1474E What Is It?

    考虑我们一定是每次构造最长的交换对. 那么就是\((1,n),(1,n - 1),...(1,\frac{n}{2} + 1)(\frac{n}{2},n)....(1,n)\)形式.

  5. 洛谷 P5400 - [CTS2019]随机立方体(组合数学+二项式反演)

    洛谷题面传送门 二项式反演好题. 首先看到"恰好 \(k\) 个极大值点",我们可以套路地想到二项式反演,具体来说我们记 \(f_i\) 为钦定 \(i\) 个点为极大值点的方案数 ...

  6. Codeforces Gym 101175F - Machine Works(CDQ 分治维护斜率优化)

    题面传送门 首先很明显我们会按照 \(d_i\) 的顺序从小到大买这些机器,故不管三七二十一先将所有机器按 \(d_i\) 从小到大排序. 考虑 \(dp\),\(dp_i\) 表示在时刻 \(d_i ...

  7. webpack--css、html 和 js 代码的常用处理

    前言 本文来总结下webpack中 css.js.html 代码常见的处理方式,学习笔记仅供参考. 正文 1.css样式文件处理 (1)提取css为一个单独的文件 在我们前面学习了webpack的基础 ...

  8. 如何从vcf文件中批量提取一系列基因的SNP位点?

    目录 需求 示例文件 代码实现 补充说明 需求 客户的一个简单需求: 我有一批功能基因位点,想从重测序的群体材料中找到这些位点,如何批量快速获得? 示例文件 gene.txt test.vcf 代码实 ...

  9. DRF知识点总结

    1. Web API接口 2. Restful接口规范 RDF请求流程及主要模块分析

  10. Python基础之基本运算符

    目录 1. 算数运算符 2. 比较运算符 3. 赋值运算符 4. 逻辑运算符 5. 身份运算 6. 运算符优先级 1. 算数运算符 常用算术运算符使用方法如下: x = 5 y = 2 a = x + ...