已索引
二进制日志的作用
二进制日志(binlog)记录了对 MySQL 数据库执行更改的所有操作,但是不包括 SELECT 和 SHOW 这类操作,因为这类操作对数据库本身并没有修改。如果想记录 select 和 show 操作,只能使用查询日志。
如果 UPDATE 操作没有引起数据库的变化,或者 select ... for update 语句是否会记录呢?
姜承尧在 《MySQL技术内幕——InnoDB存储引擎》(第2版) P73 的例子里:
update t set a = 1 where a = 2;
返回该语句影响 0 行,但 binlog 日志里是有记录该语句的。
但我在 mysql-5.7.44 和 mysql 8 里做实验时,binlog 日志里均未做记录。
对于 mysql 这类特殊的数据库,也会产生二进制日志,但 information_schema 这类没有没有物理实体的库,则不会产生二进制日志。
可以通过如下两种途径让特殊操作不产生日志:
- 拥有 super 权限的用户,可以在执行操作前,先执行 set sql_log_bin=0; 命令
- 通过 binlog_do_db 和 binlog_ignore_db 两个选项来控制哪些库产生或者不产生日志。默认都为空,表示都产生日志。
总的来说,binlog 主要用来:恢复(recovery)、复制(replication)和审计(audit)。
当然,我们还可以通过二进制日志来实现闪回功能(必须 是 ROW 格式),现在有很多基于 binlog 实现闪回功能的开源工具。 mysql 8 自带了闪回功能。
二进制日志的开启
我们在 my.cnf 模版文件中的配置如下:
server-id = 11
log_bin = bin.log
show variables 看到的值如下:
+--------------------------------------------+------------------------------+
| Variable_name | Value |
+--------------------------------------------+------------------------------+
| log_bin | ON |
| log_bin_basename | /opt/database/3306/bin |
| log_bin_index | /opt/database/3306/bin.index |
+--------------------------------------------+------------------------------+
生成的 binlog 文件名如下:
bin.000001
bin.000002
可以用 log_bin 来指定 binlog 的路径和文件名,如果 log_bin 参数不指定,则文件名默认为 "主机名-bin.日志序号",在 datadir 下。
bin.index 文件为 binlog 的索引文件,用来存储过往产生的二进制日志序号,在通常情况下,不建议手动修改这个文件。binlog 日志如果不清理,文件编号6位满了后会变成7位。
开户 binlog 确实会使数据库性能下降 1%(损失有限),但 binlog 带来了复制和不完全恢复,生产一定要打开。
对于多实例环境,开启 binlog 需要同时指定 server-id。
例如:
环境:mysql-5.7.44-linux-glibc2.12-x86_64(RHEL 7.7)
当前环境已经存在一个 3306 端口实例的情况下,下面的极简配置不能启动另外一个实例,且启动实例时 error 日志里没有任何成功或失败的记录。
[mysqld]
port = 3307
datadir = /opt/database/3307
socket = /tmp/mysql.sock.3307
log_bin = bin.log
在上面的配置文件中加入 server-id = 22 后就可以成功启动了。
binlog_format
线上必须设置为 binlog_format = ROW。
. | STATEMENT | ROW | MIXED | |
说明 | 记录操作的SQL语句 | 记录操作的每一行数据 | 混合模式 | |
优点 | 易于理解 | 数据一致性高、可flashback | 结合上述两种模式 | |
缺点 | 不支持不确定SQL语句 | 每张表一定要有主键 | 之前版本bug较多 | |
线上使用 | 不推荐 | 推荐 | 不推荐 |
注意: balckhole 存储引擎不支持 ROW,NDB 存储引擎不支持 STATEMENT。
姜:
最开始是 STATEMENT,在 MySQL 5.1 之前没有这个参数。对于复制是有一定要求的。如在主服务器运行 rand、uuid 等函数,又或者使用触发器等操作,这些都可能会导致主从服务器上表中数据的不一致(notsync)。另一个影响是,会发现 InnoDB 存储引擎的默认事务隔离级别是REPEATABLEREAD。这其实也是因为二进制日志文件格式的关系,如果使用 READ COMMITTED 的事务隔离级别(大多数数据库,如 Oracle,Microsoft SQL Server 数据库的默认隔离级别),会出现类似丢失更新的现象,从而出现主从数据库上的数据不一致。
从 MySQL 5.1 开始有 3 种格式。5.6 有几个小版本是设置的 MIXED,从 5.7 版本开始,默认都设置为了 ROW。
在 ROW 格式下,二进制日志记录的不再是简单的SQL语句了,而是记录表行更改情况。基于 ROW 格式的复制类似于 Oracle 的物理Standby。同时,对上述提及的 Statement 格式下复制的问题子以解决。从 MySQL5.1 版本开始,如果设置了 binlog_format 为 ROW,可以将 InnoDB 的事务隔离基本设为 READ COMMITTED,以获得更好的并发性。
在 MIXED 格式下,MySQL 默认采用 STATEMENT 格式进行二进制日志文件的记录,但是在一些情况下会使用 ROW 格式,可能的情况有:
1)表的存储引擎为 NDB,这时对表的 DML 操作都会以 ROW 格式记录。
2)使用了 UUID()、USER()、CURRENT_USER()、FOUND_ROWS()、ROW_COUNT() 等不确定函数。
3)使用了INSERT DELAY 语句。
4)使用了用户定义函数(UDF)。
5)使用了临时表(tcemporary table)。
其实重要相关参数
max_binlog_size:1073741824(1G)
my.cnf 模版未对该参数进行调整,默认值即是最大值 1073741824(1G)。
单个 binlog 文件的最大大小。
binlog_cache_size: 32768
my.cnf 模版未对该参数进行调整,默认 32K。此参数是基于会话的。
The size of the cache to hold changes to the binary log during a transaction.
对于非事务表来说,语句执行后就会立即写 binlog,对于事务表来说,未提交事务的 DML 操作日志会被缓存起来,事务提交时再写入 binlog,该缓存的大小由此参数定义,如果事务产生的记录大于缓存空间,则会使用一个临时文件来保存,事务结束后自动删除。
如果经常使用大事务,就需要关注此参数是否设置合理,因为该参数是基于会话的,设置太大会消耗过多内存,设置太小又可能造成使用临时文件。最理想的状态是参数值越小越好,但不要使用临时文件。
全局状态变量 Binlog_cache_use 和 Binlog_cache_disk use 可以用来判断该参数是否设置合理:
mysql> show global status like 'binlog_cache%';
+-----------------------+----------+
| Variable_name | Value |
+-----------------------+----------+
| Binlog_cache_disk_use | 560 |
| Binlog_cache_use | 92764233 |
+-----------------------+----------+
2 rows in set (0.00 sec)
Binlog_cache_use 显示了使用 binlog cache 的事务数,Binlog_cache_disk_use 则显示了使用临时文件的事务数。如果频繁使用到了临时文件,就应该特别引起关注。
max_binlog_cache_size
my.cnf 模版未对该参数进行调整,32位默认即是最大值4G,64位默认即是最大值 16777216PB,可以认为就是没有限制了。如果一个事务产生的 binlog 日志大于该值,事务会报错回滚。
If a transaction requires more than this many bytes, the server generates a error:
Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage
sync_binlog
Controls how often the MySQL server synchronizes the binary log to disk.
MySQL 写 binlog 就跟我们写文件一样,可能并没有真正落盘,我们有时为了真正落盘,操作系统提供了 sync 命令。sync_binlog 用来定义 binlog 真正落盘的策略。生产中该参数始终配置为1(最安全),5.7.7 及之后默认值也是1,可以不用过多去研究。
sync_binlog=0: Disables synchronization of the binary log to disk by the MySQL server.
Instead, the MySQL server relies on the operating system to flush the binary log to disk from time to time as it does for any other file. This setting provides the best performance, but in the event of a power failure or operating system crash, it is possible that the server has committed transactions that have not been synchronized to the binary log.
sync_binlog=1: Enables synchronization of the binary log to disk before transactions are
- This is the safest setting but can have a negative impact on performance due to
- increased number of disk writes. In the event of a power failure or operating system crash,
transactions that are missing from the binary log are only in a prepared state. This permits the
automatic recovery routine to roll back the transactions, which guarantees that no transaction is
lost from the binary log. 之前默认值是0,现在已经是1了。
sync_binlog=N, where N is a value other than 0 or 1: The binary log is synchronized to disk
after N binary log commit groups have been collected. In the event of a power failure or operating system crash, it is possible that the server has committed transactions that have not been flushed to the binary log. This setting can have a negative impact on performance due to the increased number of disk writes. A higher value improves performance, but with an increased risk of data loss
For the greatest possible durability and consistency in a replication setup that uses InnoDB with
transactions, use these settings: (my.cnf 模版已经照此配置)
• sync_binlog=1.
• innodb_flush_log_at_trx_commit=1.
Caution:
Many operating systems and some disk hardware fool the flush-to-disk operation. They may tell mysqld that the flush has taken place, even though it has not. In this case, the durability of transactions is not guaranteed even with the recommended settings, and in the worst case, a power outage can corrupt InnoDB data. Using a battery-backed disk cache in the SCSI disk
controller or in the disk itself speeds up file flushes, and makes the operation safer. You can also try to disable the caching of disk writes in hardware caches.
innodb_support_xa
该参数默认开启,从 MySQL 5.7.10 开启,不允许禁用,MySQL 8.0 移除了该参数。可以不用过多去研究。
Enables InnoDB support for two-phase commit in XA transactions, causing an extra disk flush for transaction preparation. The XA mechanism is used internally and is essential for any server that has its binary log turned on and is accepting changes to its data from more than one thread. If you disable innodb_support_xa, transactions can be written to the binary log in a different order than the live database is committing them, which can produce different data when the binary log is replayed in disaster recovery or on a replica. Do not disable innodb_support_xa on a replication source server unless you have an unusual setup where only one thread is able to change data.
innodb_support_xa is deprecated; expect it to be removed in a future MySQL release. InnoDB
support for two-phase commit in XA transactions is always enabled as of MySQL 5.7.10.
Disabling innodb_support_xa is no longer permitted as it makes replication unsafe and prevents
performance gains associated with binary log group commit.
XA Distributed Transaction support is enabled by default. If you are not using this feature, you can disable the innodb_support_xa configuration option, avoiding the performance overhead of an extra fsync for each transaction.
As of MySQL 5.7.10, disabling innodb_support_xa is not permitted as it makes replication unsafe and prevents performance gains associated with binary log group commit. The innodb_support_xa configuration option is removed in MySQL 8.0.
The innodb_support_xa system variable, which enables InnoDB support for two-phase commit
in XA transactions, is deprecated as of MySQL 5.7.10. InnoDB support for two-phase commit in XA transactions is always enabled as of MySQL 5.7.10.
姜承尧 《MySQL技术内幕——InnoDB存储引擎》(第2版) P77:
但是,即使将 sync_binlog 设为1,还是会有一种情况导致问题的发生。当使用 ImnoDB 存储引擎时,在一个事务发出 COMMIT 动作之前,由于 sync_binlog 为1,因此会将二进制日志立即写人磁盘。如果这时已经写人了二进制日志,但是提交还没有发生,并且此时发生了容机,那么在 MySQL 数据库下次启动时,由于 COMMIT 操作并没有发生,这个事务会被回滚掉。但是二进制日志已经记录了该事务信息,不能被回滚。这个问题可以通过将参数 imnnodb_support_xa 设为 1 来解决,虽然 innodb_support_xa 与 XA 事务有关,但它同时也确保了二进制日志和 InnoDB 存储引擎数据文件的同步。
Old Boy:
默认情况下,二进制日志不是实时同步到磁盘,因此如果操作系统崩溃或者机器故障,存在数据丢失的可能。要防止这种情况的出现,需要考虑的因素比较多,仅从 MSQL 的二进制日志同步来说,可以设置二进制日志同步到磁盘的频率,MySQL 提供了专用的系统变量 sync_binog。该参数的详细说明颇费幅,这里先简要描述与本节主题相关的内容。sync_binlog 值设为 1 安全级别最高,同时也是最慢的设置,不过即使设置为 1 同样有可能存在丢失数据的可能,只是最坏情况下,仅丢失最后执行的那条语句或事务。举例来说,使用 InnoDB 引擎的表通过事务向表中写数据,操作已经写到二进制日志,但还没来得及将提交语句写入日志,这时系统崩溃,那么当数据库服务重新启动时,InnoDB 引擎肯定会将未提交的事务回滚,那么这种情况下,必然造成数据丢失。
要解决这种问题,MySQL 另外又提供了初始化参数 --innodb-support-xa,设置该参数值为 1,启用分布式事务的支持,确保二进制日志与 InnoDB 数据文件的同步。
这种选项提供了深度的安全性,MySOL 应被配置为以事务为单位同步二进制日志和 InnoDB 日志到磁盘,InnoDB 日志默认即是同步状态,sync_binlog=1 可以同步二进制日志。这样当 MySQL 服务从崩溃中恢复时,为事务执行回滚后,MySQL 服务中断二进制日志中 InnoDB 事务的回滚,以这种方式确保二进制日志能够考虑 InnoDB 表中的实际数据,同样,Slave端也会保持同步状态(因为没有收到回滚的语句)。
当 MSQL 服务执行崩溃恢复时发现,二进制日志比期望中要少,比如 InnoDB 事务缺少 commit (当syncbinlog=l时不可能出现这种情况),服务器端就会抛出错误消息:The binary log file_name is shorter than itsexpected size,这种情况下,说明二进制日志文件有误,复制环境有必要重建。
查看二进制日志
我们可以使用 show 命令 或者 mysqlbinlog 工具来查看和分析二进制日志。
查看当前正在使用的二进制文件
mysql> show master status; <--- 查看当前 binlog,Positon 表示当前文件已经写到的位置,代表了当前日志文件的大小,单位为字节
+------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------+----------+--------------+------------------+-------------------+
| bin.000007 | 154 | | demodb | |
+------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql> flush binary logs; <--- 刷新 binlog,会生成新的 binlog 日志
Query OK, 0 rows affected (0.01 sec)
mysql> show master status; <--- 查看新的 binlog 位置
+------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------+----------+--------------+------------------+-------------------+
| bin.000008 | 154 | | demodb | |
+------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
除非用命令查看,也可以直接看操作系统上生成的文件,最后一个文件就是当前正在使用的日志文件。
show 命令查看二进制文件中的事件
官方文档:https://dev.mysql.com/doc/refman/5.7/en/show-binlog-events.html
mysql> show binlog events in 'bin.000007';
+------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------+-----+----------------+-----------+-------------+---------------------------------------+
| bin.000007 | 4 | Format_desc | 22 | 123 | Server ver: 5.7.44-log, Binlog ver: 4 |
| bin.000007 | 123 | Previous_gtids | 22 | 154 | |
| bin.000007 | 154 | Rotate | 22 | 195 | bin.000008;pos=4 |
+------------+-----+----------------+-----------+-------------+---------------------------------------+
3 rows in set (0.00 sec)
mysql> show binlog events in 'bin.000008'; <--- 查看 binlog 中内容,如果不指定文件,则从第一个文件开始,如果文件不存在,会报错
+------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------+-----+----------------+-----------+-------------+---------------------------------------+
| bin.000008 | 4 | Format_desc | 22 | 123 | Server ver: 5.7.44-log, Binlog ver: 4 |
| bin.000008 | 123 | Previous_gtids | 22 | 154 | |
+------------+-----+----------------+-----------+-------------+---------------------------------------+
2 rows in set (0.00 sec)
binlog 是由各种类型的 event 组成。
每个二进制日志由三个部分的 event 组成:Header + Binary Log Events + Rotate。
每个日志文件的开头有个叫 Format_desc 的 event,用来记录 Sever 的版本号和 Binlog 的版本号。5.7 加了一个叫 Previous_gtids 的 event。
如果文件结束了,有一个叫 Rotate 的 event,Info 列会指下一个文件的起始位置。
中间就是具体的 Binary Log Events。
每个 event 由(Log_name,Pos)一起来定义。Pos 是 event 的起始位置,End_log_pos 是结束位置。End_log_pos - Pos 就是该 event 占用的字节数。每一行的记录,但是经过 base64 加密过的,这样方便传输, base64 在 web 中是应用比较广的。
下面看一下表的创建、删除与 INSERT, UPDATE, DELETE 在二进制日志是如何记录的:
mysql> create table cyt (id int, name varchar(20));
Query OK, 0 rows affected (0.05 sec)
mysql> insert cyt values (1,'a');
Query OK, 1 row affected (0.03 sec)
mysql> update cyt set id=2 where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> delete from cyt where id=2;
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.01 sec)
mysql> drop table cyt;
Query OK, 0 rows affected (0.01 sec)
mysql> show binlog events in 'bin.000011';
+------------+-----+----------------+-----------+-------------+-----------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------+-----+----------------+-----------+-------------+-----------------------------------------------------------+
| bin.000011 | 4 | Format_desc | 22 | 123 | Server ver: 5.7.44-log, Binlog ver: 4 |
| bin.000011 | 123 | Previous_gtids | 22 | 154 | |
| bin.000011 | 154 | Anonymous_Gtid | 22 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| bin.000011 | 219 | Query | 22 | 340 | use `demodb`; create table cyt (id int, name varchar(20)) |
| bin.000011 | 340 | Anonymous_Gtid | 22 | 405 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| bin.000011 | 405 | Query | 22 | 479 | BEGIN |
| bin.000011 | 479 | Table_map | 22 | 530 | table_id: 110 (demodb.cyt) |
| bin.000011 | 530 | Write_rows | 22 | 572 | table_id: 110 flags: STMT_END_F |
| bin.000011 | 572 | Table_map | 22 | 623 | table_id: 110 (demodb.cyt) |
| bin.000011 | 623 | Update_rows | 22 | 673 | table_id: 110 flags: STMT_END_F |
| bin.000011 | 673 | Table_map | 22 | 724 | table_id: 110 (demodb.cyt) |
| bin.000011 | 724 | Delete_rows | 22 | 766 | table_id: 110 flags: STMT_END_F |
| bin.000011 | 766 | Xid | 22 | 797 | COMMIT /* xid=38 */ |
| bin.000011 | 797 | Anonymous_Gtid | 22 | 862 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| bin.000011 | 862 | Query | 22 | 982 | use `demodb`; DROP TABLE `cyt` /* generated by server */ |
+------------+-----+----------------+-----------+-------------+-----------------------------------------------------------+
15 rows in set (0.00 sec)
Table_map 表示这张表的定义和每个列的类型。
Write_rows 表示操作类型是写入一个 rows,但是具体操作是看不到的, 同理有 Update_rows, Delete_rows。
默认只能知道每一行的变化,但是不知道变化的操作的 SQL 语句是什么,如果想知道, binlog_rows_query_log_events 设置为 1。(my.cnf 文件中已经新加了该参数)
配置后效果如下:
mysql> insert into cyt2 values(3);
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> commit;
Query OK, 0 rows affected (0.01 sec)
mysql> show binlog events in 'bin.000018';
+------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------+-----+----------------+-----------+-------------+---------------------------------------+
| bin.000018 | 4 | Format_desc | 22 | 123 | Server ver: 5.7.44-log, Binlog ver: 4 |
| bin.000018 | 123 | Previous_gtids | 22 | 154 | |
| bin.000018 | 154 | Anonymous_Gtid | 22 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| bin.000018 | 219 | Query | 22 | 293 | BEGIN |
| bin.000018 | 293 | Rows_query | 22 | 343 | # insert into cyt2 values(3) |
| bin.000018 | 343 | Table_map | 22 | 392 | table_id: 111 (demodb.cyt2) |
| bin.000018 | 392 | Write_rows | 22 | 432 | table_id: 111 flags: STMT_END_F |
| bin.000018 | 432 | Xid | 22 | 463 | COMMIT /* xid=9 */ |
+------------+-----+----------------+-----------+-------------+---------------------------------------+
8 rows in set (0.00 sec)
通过 mysqlbinlog 也能看到记录了语句:
# mysqlbinlog -vv --base64-output=decode-rows bin.000018
# at 293
#250717 16:59:25 server id 22 end_log_pos 343 CRC32 0x310a4566 Rows_query
# insert into cyt2 values(3)
生产上 binlog 日志通常很多,直接查看文件中的所有内容将是一个耗时和耗资源的一个过程。
Issuing a SHOW BINLOG EVENTS with no LIMIT clause could start a very time- and resource-consuming process because the server returns to the client the complete contents of the binary log (which includes all statements executed by the server that modify data).
此时,我们可以使用 from 定位和 limit 限制。
SHOW BINLOG EVENTS
[IN 'log_name']
[FROM pos]
[LIMIT [offset,] row_count]
仅查看前5条 events:
mysql> show binlog events in 'bin.000011' limit 5;
+------------+-----+----------------+-----------+-------------+-----------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------+-----+----------------+-----------+-------------+-----------------------------------------------------------+
| bin.000011 | 4 | Format_desc | 22 | 123 | Server ver: 5.7.44-log, Binlog ver: 4 |
| bin.000011 | 123 | Previous_gtids | 22 | 154 | |
| bin.000011 | 154 | Anonymous_Gtid | 22 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| bin.000011 | 219 | Query | 22 | 340 | use `demodb`; create table cyt (id int, name varchar(20)) |
| bin.000011 | 340 | Anonymous_Gtid | 22 | 405 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
+------------+-----+----------------+-----------+-------------+-----------------------------------------------------------+
5 rows in set (0.00 sec)
查看从 pos 530 开始的所有日志:
mysql> show binlog events in 'bin.000011' from 530;
+------------+-----+----------------+-----------+-------------+----------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------+-----+----------------+-----------+-------------+----------------------------------------------------------+
| bin.000011 | 530 | Write_rows | 22 | 572 | table_id: 110 flags: STMT_END_F |
| bin.000011 | 572 | Table_map | 22 | 623 | table_id: 110 (demodb.cyt) |
| bin.000011 | 623 | Update_rows | 22 | 673 | table_id: 110 flags: STMT_END_F |
| bin.000011 | 673 | Table_map | 22 | 724 | table_id: 110 (demodb.cyt) |
| bin.000011 | 724 | Delete_rows | 22 | 766 | table_id: 110 flags: STMT_END_F |
| bin.000011 | 766 | Xid | 22 | 797 | COMMIT /* xid=38 */ |
| bin.000011 | 797 | Anonymous_Gtid | 22 | 862 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| bin.000011 | 862 | Query | 22 | 982 | use `demodb`; DROP TABLE `cyt` /* generated by server */ |
+------------+-----+----------------+-----------+-------------+----------------------------------------------------------+
8 rows in set (0.00 sec)
从 pos 530 开始,仅显示4条 events:
mysql> show binlog events in 'bin.000011' from 530 limit 4;
+------------+-----+-------------+-----------+-------------+---------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------+-----+-------------+-----------+-------------+---------------------------------+
| bin.000011 | 530 | Write_rows | 22 | 572 | table_id: 110 flags: STMT_END_F |
| bin.000011 | 572 | Table_map | 22 | 623 | table_id: 110 (demodb.cyt) |
| bin.000011 | 623 | Update_rows | 22 | 673 | table_id: 110 flags: STMT_END_F |
| bin.000011 | 673 | Table_map | 22 | 724 | table_id: 110 (demodb.cyt) |
+------------+-----+-------------+-----------+-------------+---------------------------------+
4 rows in set (0.00 sec)
从 pos 530 后面的第 3 条开始,显示5条 events:
mysql> show binlog events in 'bin.000011' from 530 limit 3,5;
+------------+-----+----------------+-----------+-------------+----------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------+-----+----------------+-----------+-------------+----------------------------------------------------------+
| bin.000011 | 673 | Table_map | 22 | 724 | table_id: 110 (demodb.cyt) |
| bin.000011 | 724 | Delete_rows | 22 | 766 | table_id: 110 flags: STMT_END_F |
| bin.000011 | 766 | Xid | 22 | 797 | COMMIT /* xid=38 */ |
| bin.000011 | 797 | Anonymous_Gtid | 22 | 862 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| bin.000011 | 862 | Query | 22 | 982 | use `demodb`; DROP TABLE `cyt` /* generated by server */ |
+------------+-----+----------------+-----------+-------------+----------------------------------------------------------+
5 rows in set (0.00 sec)
mysqlbinlog 工具查看二进制文件中的事件
使用 mysqlbinlog 命令时,可以跟多个 binlog 文件,也可以使用通配。
# mysqlbinlog [-vv] bin.000011
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#250717 15:19:04 server id 22 end_log_pos 123 CRC32 0xc3d2ae7d Start: binlog v 4, server v 5.7.44-log created 250717 15:19:04
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
6KN4aA8WAAAAdwAAAHsAAAABAAQANS43LjQ0LWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
AX2u0sM=
'/*!*/;
# at 123
#250717 15:19:04 server id 22 end_log_pos 154 CRC32 0xa4f2382e Previous-GTIDs
# [empty]
# at 154
#250717 15:19:39 server id 22 end_log_pos 219 CRC32 0xbc7e99a9 Anonymous_GTID last_committed=0 sequence_number=1 rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 219
#250717 15:19:39 server id 22 end_log_pos 340 CRC32 0x0aa0e6a7 Query thread_id=2 exec_time=0 error_code=0
use `demodb`/*!*/;
SET TIMESTAMP=1752736779/*!*/;
SET @@session.pseudo_thread_id=2/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1436549152/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create table cyt (id int, name varchar(20))
/*!*/;
# at 340
#250717 15:20:40 server id 22 end_log_pos 405 CRC32 0xac867f22 Anonymous_GTID last_committed=1 sequence_number=2 rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 405
#250717 15:19:56 server id 22 end_log_pos 479 CRC32 0x9bb0a06d Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1752736796/*!*/;
BEGIN
/*!*/;
# at 479
#250717 15:19:56 server id 22 end_log_pos 530 CRC32 0xe6e2c795 Table_map: `demodb`.`cyt` mapped to number 110
# at 530
#250717 15:19:56 server id 22 end_log_pos 572 CRC32 0xc94ce40c Write_rows: table id 110 flags: STMT_END_F
BINLOG '
HKR4aBMWAAAAMwAAABICAAAAAG4AAAAAAAEABmRlbW9kYgADY3l0AAIDDwIUAAOVx+Lm
HKR4aB4WAAAAKgAAADwCAAAAAG4AAAAAAAEAAgAC//wBAAAAAWEM5EzJ
'/*!*/;
### INSERT INTO `demodb`.`cyt`
### SET
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
### @2='a' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
# at 572
#250717 15:20:16 server id 22 end_log_pos 623 CRC32 0x96fc3fb6 Table_map: `demodb`.`cyt` mapped to number 110
# at 623
#250717 15:20:16 server id 22 end_log_pos 673 CRC32 0x83c3949b Update_rows: table id 110 flags: STMT_END_F
BINLOG '
MKR4aBMWAAAAMwAAAG8CAAAAAG4AAAAAAAEABmRlbW9kYgADY3l0AAIDDwIUAAO2P/yW
MKR4aB8WAAAAMgAAAKECAAAAAG4AAAAAAAEAAgAC///8AQAAAAFh/AIAAAABYZuUw4M=
'/*!*/;
### UPDATE `demodb`.`cyt`
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
### @2='a' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
### SET
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
### @2='a' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
# at 673
#250717 15:20:28 server id 22 end_log_pos 724 CRC32 0x1fbddede Table_map: `demodb`.`cyt` mapped to number 110
# at 724
#250717 15:20:28 server id 22 end_log_pos 766 CRC32 0x3319b98e Delete_rows: table id 110 flags: STMT_END_F
BINLOG '
PKR4aBMWAAAAMwAAANQCAAAAAG4AAAAAAAEABmRlbW9kYgADY3l0AAIDDwIUAAPe3r0f
PKR4aCAWAAAAKgAAAP4CAAAAAG4AAAAAAAEAAgAC//wCAAAAAWGOuRkz
'/*!*/;
### DELETE FROM `demodb`.`cyt`
### WHERE
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
### @2='a' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
# at 766
#250717 15:20:40 server id 22 end_log_pos 797 CRC32 0xa9f4bd1c Xid = 38
COMMIT/*!*/;
# at 797
#250717 15:20:43 server id 22 end_log_pos 862 CRC32 0x79d2de35 Anonymous_GTID last_committed=2 sequence_number=3 rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 862
#250717 15:20:43 server id 22 end_log_pos 982 CRC32 0x2d2ee1e9 Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1752736843/*!*/;
DROP TABLE `cyt` /* generated by server */
/*!*/;
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*/;
如果没有 -vv,就不能看到类似 SQL 的语句,可以看到,除了 create table、drop table 外,都是经过 base64 加密的数据。
一定要注意,binlog 里面记录的不是 SQL 语句。 @1 表示第1个列,@2表示第2个列
insert 和 delete 都是记录整行, update 记录行的前项和后项,所以影响记录数相同的情况下 update 是最消耗日志空间。
ROW 格式记录的是每行一操作,所以能确保主从的数据严格一致。缺点是日志数据可能很大,比如 update 全表, delete 全表。
如果想看 base64 的编码原文,可以使用 --base64-output=decode-rows 来 decodes row events into commented pseudo-SQL statements。
# mysqlbinlog -vv --base64-output=decode-rows bin.000010
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#250717 14:29:16 server id 22 end_log_pos 123 CRC32 0x575e6377 Start: binlog v 4, server v 5.7.44-log created 250717 14:29:16
# Warning: this binlog is either in use or was not closed properly.
# at 123
#250717 14:29:16 server id 22 end_log_pos 154 CRC32 0x25ab28cd Previous-GTIDs
# [empty]
# at 154
#250717 14:30:20 server id 22 end_log_pos 219 CRC32 0xe71c29d5 Anonymous_GTID last_committed=0 sequence_number=1 rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 219
#250717 14:30:20 server id 22 end_log_pos 322 CRC32 0x462f7003 Query thread_id=2 exec_time=0 error_code=0
use `demodb`/*!*/;
SET TIMESTAMP=1752733820/*!*/;
SET @@session.pseudo_thread_id=2/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1436549152/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create table cyt (id int)
/*!*/;
# at 322
#250717 14:33:06 server id 22 end_log_pos 387 CRC32 0x657e3a57 Anonymous_GTID last_committed=1 sequence_number=2 rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 387
#250717 14:30:29 server id 22 end_log_pos 461 CRC32 0x4364f414 Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1752733829/*!*/;
BEGIN
/*!*/;
# at 461
#250717 14:30:29 server id 22 end_log_pos 509 CRC32 0x18448aa9 Table_map: `demodb`.`cyt` mapped to number 109
# at 509
#250717 14:30:29 server id 22 end_log_pos 549 CRC32 0xd0ff2fb8 Write_rows: table id 109 flags: STMT_END_F
### INSERT INTO `demodb`.`cyt`
### SET
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
# at 549
#250717 14:30:57 server id 22 end_log_pos 597 CRC32 0xdf967ad3 Table_map: `demodb`.`cyt` mapped to number 109
# at 597
#250717 14:30:57 server id 22 end_log_pos 643 CRC32 0x63a4649c Update_rows: table id 109 flags: STMT_END_F
### UPDATE `demodb`.`cyt`
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
### SET
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
# at 643
#250717 14:33:03 server id 22 end_log_pos 691 CRC32 0x9ac014cd Table_map: `demodb`.`cyt` mapped to number 109
# at 691
#250717 14:33:03 server id 22 end_log_pos 731 CRC32 0x6760e0eb Delete_rows: table id 109 flags: STMT_END_F
### DELETE FROM `demodb`.`cyt`
### WHERE
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
# at 731
#250717 14:33:06 server id 22 end_log_pos 762 CRC32 0xc085329e Xid = 11
COMMIT/*!*/;
# at 762
#250717 14:33:21 server id 22 end_log_pos 827 CRC32 0x9d6f245f Anonymous_GTID last_committed=2 sequence_number=3 rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 827
#250717 14:33:21 server id 22 end_log_pos 947 CRC32 0xda1a6a08 Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1752734001/*!*/;
DROP TABLE `cyt` /* generated by server */
/*!*/;
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@mysqlnode1 3307]#
binlog 中会产生 rollback 的信息吗?
不会的。在以前的版本里,引擎混用可能会记录 rollback 信息,在 5.7.44 里测试已经不会记录了。
mysql> create table cyt1(id int) engine=myisam;
mysql> create table cyt2(id int) engine=innodb;
仅使用 innodb 引擎,不记录 rollback:
mysql> flush binary logs;
Query OK, 0 rows affected (0.02 sec)
mysql> show master status;
+------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------+----------+--------------+------------------+-------------------+
| bin.000015 | 154 | | | |
+------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql> insert into cyt2 values(1);
Query OK, 1 row affected (0.01 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
查看 binlog 日志:
# mysqlbinlog -vv bin.000015
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#250717 16:00:24 server id 22 end_log_pos 123 CRC32 0xa073daaf Start: binlog v 4, server v 5.7.44-log created 250717 16:00:24
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
mK14aA8WAAAAdwAAAHsAAAABAAQANS43LjQ0LWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
Aa/ac6A=
'/*!*/;
# at 123
#250717 16:00:24 server id 22 end_log_pos 154 CRC32 0x8e3b9ec9 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*/;
引擎混合1:
mysql> flush binary logs;
Query OK, 0 rows affected (0.01 sec)
mysql> show master status;
+------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------+----------+--------------+------------------+-------------------+
| bin.000016 | 154 | | | |
+------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql>
mysql> insert into cyt2 values(1);
Query OK, 1 row affected (0.00 sec)
mysql> insert into cyt1 values(1);
Query OK, 1 row affected (0.01 sec)
mysql> rollback;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql>
# mysqlbinlog -vv bin.000016
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#250717 16:07:29 server id 22 end_log_pos 123 CRC32 0xa09cb40d Start: binlog v 4, server v 5.7.44-log created 250717 16:07:29
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
Qa94aA8WAAAAdwAAAHsAAAABAAQANS43LjQ0LWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
AQ20nKA=
'/*!*/;
# at 123
#250717 16:07:29 server id 22 end_log_pos 154 CRC32 0x559e4846 Previous-GTIDs
# [empty]
# at 154
#250717 16:10:47 server id 22 end_log_pos 219 CRC32 0xef04ac05 Anonymous_GTID last_committed=0 sequence_number=1 rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 219
#250717 16:10:47 server id 22 end_log_pos 293 CRC32 0xe6526b61 Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1752739847/*!*/;
SET @@session.pseudo_thread_id=2/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1436549152/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 293
#250717 16:10:47 server id 22 end_log_pos 342 CRC32 0x42575820 Table_map: `demodb`.`cyt1` mapped to number 115
# at 342
#250717 16:10:47 server id 22 end_log_pos 382 CRC32 0x0ef88b68 Write_rows: table id 115 flags: STMT_END_F
BINLOG '
B7B4aBMWAAAAMQAAAFYBAAAAAHMAAAAAAAEABmRlbW9kYgAEY3l0MQABAwABIFhXQg==
B7B4aB4WAAAAKAAAAH4BAAAAAHMAAAAAAAEAAgAB//4BAAAAaIv4Dg==
'/*!*/;
### INSERT INTO `demodb`.`cyt1`
### SET
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
# at 382
#250717 16:10:47 server id 22 end_log_pos 457 CRC32 0xbb41c65f Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1752739847/*!*/;
COMMIT
/*!*/;
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*/;
引擎混用2:
mysql> flush binary logs;
Query OK, 0 rows affected (0.01 sec)
mysql> show master status;
+------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------+----------+--------------+------------------+-------------------+
| bin.000017 | 154 | | | |
+------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql> insert into cyt1 values(2);
Query OK, 1 row affected (0.01 sec)
mysql> insert into cyt2 values(2);
Query OK, 1 row affected (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected, 1 warning (0.01 sec)
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#250717 16:13:06 server id 22 end_log_pos 123 CRC32 0xc5770629 Start: binlog v 4, server v 5.7.44-log created 250717 16:13:06
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
krB4aA8WAAAAdwAAAHsAAAABAAQANS43LjQ0LWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
ASkGd8U=
'/*!*/;
# at 123
#250717 16:13:06 server id 22 end_log_pos 154 CRC32 0xa353384c Previous-GTIDs
# [empty]
# at 154
#250717 16:14:15 server id 22 end_log_pos 219 CRC32 0x7f150385 Anonymous_GTID last_committed=0 sequence_number=1 rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 219
#250717 16:14:15 server id 22 end_log_pos 293 CRC32 0x2fa51f37 Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1752740055/*!*/;
SET @@session.pseudo_thread_id=2/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1436549152/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 293
#250717 16:14:15 server id 22 end_log_pos 342 CRC32 0x89bd6a67 Table_map: `demodb`.`cyt1` mapped to number 115
# at 342
#250717 16:14:15 server id 22 end_log_pos 382 CRC32 0xa924c8cc Write_rows: table id 115 flags: STMT_END_F
BINLOG '
17B4aBMWAAAAMQAAAFYBAAAAAHMAAAAAAAEABmRlbW9kYgAEY3l0MQABAwABZ2q9iQ==
17B4aB4WAAAAKAAAAH4BAAAAAHMAAAAAAAEAAgAB//4CAAAAzMgkqQ==
'/*!*/;
### INSERT INTO `demodb`.`cyt1`
### SET
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
# at 382
#250717 16:14:15 server id 22 end_log_pos 457 CRC32 0x3980c5ea Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1752740055/*!*/;
COMMIT
/*!*/;
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*/;
可见,引擎混用只记录了 MyISAM 的,没有 InonoDB 的。