MySQL 的 binlog(binary log) 是一种日志文件,它记录了所有对数据库的数据更改操作,包括插入、更新、删除等。
主用于主从复制和数据恢复等操作。
binlog 文件的格式有三种主要类型:STATEMENT、ROW 和 MIXED。
1. STATEMENT 格式
在 STATEMENT 格式下,binlog 不记录每一行数据的变化,记录的是执行的 SQL 语句。是导致数据变更的 SQL 语句。
优点:
存储空间相对较小,因为记录的是 SQL 语句,而不是每一行的变化。
在数据量较少或操作较简单的情况下,可以减少 binlog 文件的大小。
缺点:
如果 SQL 语句执行的上下文环境发生了变化(如某些数据的内容或环境不同),则可能会导致从服务器的数据不一致,因为从服务器会执行与主服务器相同的 SQL 语句。
例如,某些 SQL 语句可能会依赖于表的特定状态或外部条件,导致从服务器执行时产生不同的结果:
UPDATE employees SET salary = 1000 WHERE id = 1;
//如果 主服务器 上,ID 为 1 的员工存在,执行成功。
//如果 从服务器 上,ID 为 1 的员工不存在,执行 SQL 后不会有任何变化。
UPDATE employees SET salary = salary * 1.05 WHERE join_date < NOW();
//在主服务器上,NOW() 可能返回一个特定的时间,假设当前是 2024 年 11 月 17 日。
//如果从服务器的时间比主服务器的时间晚或早,NOW() 的结果就会不同,从而导致 SQL 语句影响的行数和数据可能不同。
2. ROW 格式
在 ROW 格式下,binlog 记录每一行数据的变化,不是执行的 SQL 语句。具体说,它记录了哪些行数据被插入、更新或删除。
优点:
更精确,每个操作都被记录为数据行的变化,确保了主从服务器的数据一致性。
在一些复杂的 SQL 操作中,ROW 格式能更好地反映数据的实际变动。
缺点:
由于每行数据的变化都被记录下来,binlog 的存储空间相对较大。
当表中数据变化频繁时,生成的 binlog 文件也会较大。
3. MIXED 格式
MIXED 格式是 STATEMENT 和 ROW 格式的混合体。MySQL 会根据执行的具体 SQL 语句决定使用 STATEMENT 还是 ROW 格式。
在简单的 SQL 语句(如 UPDATE、INSERT)下使用 STATEMENT 格式。
在更复杂的 SQL 操作下(如涉及了不确定性操作或会有副作用的操作),会自动切换为 ROW 格式。
优点:
在常见的查询中使用 STATEMENT 格式,能够有效减少 binlog 文件的大小。
在复杂查询时使用 ROW 格式,保证了主从数据的一致性。
缺点:
配置\调试更复杂,因为 MySQL 自动根据 SQL 语句的复杂性选择不同的日志格式。
4、配置和查看 binlog 格式
MySQL 支持通过配置文件设置 binlog 格式,可通过 my.cnf (Linux : /etc/mysql/my.cnf) 或 my.ini (Windows)文件进行配置:
[mysqld]
log-bin = mysql-bin
binlog-format = ROW # 可选值: STATEMENT, ROW, MIXED
或者在运行时查看当前的 binlog 格式:
SHOW VARIABLES LIKE 'binlog_format';
5、使用场景:
STATEMENT :对数据一致性要求不高且操作简单的场景。
ROW :数据一致性要求较高的环境,尤其是主从复制和高可用性架构中。
MIXED :适合大多数情况下的使用,结合了两者的优点