MySQL binlog 日志的格式

1. binlog 日志格式

binlog 日志有两种格式,statement-based 和 row-based。
当使用 statement-based 方式,Master 将 SQL 语句写入binary log 文件,slave 获取到 binary log 文件以后,执行其中的 SQL 语句。
当使用 row-based 方式,Master 会将表中每一行的修改都记录到 binary log 文件中,slave 获取到 binary log 文件后逐行实现这些修改。
你也可以配置 MySQL 混合使用这两种方式(MIXED FORMAT),即同时使用 statement-based 和 row-based ,在记录日志时,MySQL 会选择最适合的方式来记录日志。当使用混合日志时,statement-based 是默认的日志格式,但是在某些情况下会自动切换为 row-based 格式来记录日志,具体格式由使用的存储引擎和执行的语句共同决定。具体可参见:Mixed Binary Logging Format

Note:
MySQL 5.7.7 之前,默认的格式是 statement-based,5.7.7及以后的版本,row-based 是默认的日志格式。

2. Statement-Based 和 Row-Based 的优点和缺点

每种日志格式都有优点和缺点,对于大部分用户,混合模式(MIXED FORMAT) 也许是最好的(provide the best combination of data integrity and perfomance)。

1. Statement-Based 优点:

  • 久经验证的技术
  • 写入 log 文件的数据更少,同时恢复数据时也更快。
  • log 文件包含所有的改变数据库的语句,可以用来审计数据库(audit database)。(?)

2. Statement-Based 缺点:

  • 不是所有修改数据的语句都可以使用 statement-based 方式记录日志,一些不确定的操作就很难使用 statement-based 方式记录。比如下面的一些 DML 语句:
    • 一个 DML 语句如果依赖不确定的 UDF 或存储方法(stored program),就不能使用 Statement-Based 方式记录,因为这个 DML 语句的执行结果会受这些不确定的 UDF 或存储方法的影响。
    • DELETE 和 UPDATE 语句如果使用了 LIMIT 但是没有使用 ORDER BY,那么结果也是不确定的,也不能使用 Statement-Based 方式记录日志。Replication and LIMIT
    • 使用了下面方法的语句不能使用 Statement-Based 方式记录日志:
      LOAD_FILE()
      UUID(), UUID_SHORT()
      USER()
      FOUND_ROWS()
      SYSDATE() (除非Master 和 Slave 在启动时都添加了 –sysdate-is-now 选项)
      GET_LOCK()
      IS_FREE_LOCK()
      IS_USER_LOCK()
      MASTER_POS_WAIT()
      RAND()
      RELEASE_LOCK()
      SLEEP()
      VERSION()
      其他的函数都可以使用 Statement-Based 方式记录日志,包括 NOW() 之类的。详情可参见:Replication and System Functions
  • INSERT … SELECT 语句使用 Statement-Based 方式比 Row-Based 方式需要更多的行级锁。
  • UPDATE 语句需要全表扫描时(where 条件的字段未设置索引),Statement-Based 方式需要更多的锁(译者注:貌似需要锁全表)
  • 对于 InnoDB 引擎,一个带有 AUTO_INCREMENT 的 INSERT 语句会阻塞其他的 INSERT 语句。
  • Stored functions execute with the same NOW() value as the calling statement. However, this is not true of stored procedures.
  • 使用 Statement-Based 方式记录日志,语句里的 NOW() 在主从两台机器上会得到相同的值,
  • Master 和 Slave 上的表结构必须完全一致。Replication with Differing Table Definitions on Master and Slave

3. Row-Based 优点:

  • 所有的改变都可以写入到日志,这也是最安全的方式。
  • 对于任何 INSERT/UPDATE/DELETE 操作,Row-Based 方式需要更少的行锁。
  • 对于下面的语句,Row-Based 方式使得 Master 需要更少的行锁,因此可以获得更高的性能:(这个有点看不懂,跟 Master 有什么关系?)
    • INSERT … SELECT
    • 带有 AUTO_INCREMENT 的 INSERT
    • UPDATE/DELETE 语句的 where 条件字段没有设置索引

Note:
更新数据库信息的语句,比如 GRANT,REVOKE 和对触发器、视图、存储程序(包括存储过程)的操作,都是使用 Statement-Based 方式写日志。(是不是 DDL 语句都是使用 Statement-Based 方式呢?)

4. Row-Based 缺点:

  • Row-Based 方式会使得更多的数据被写入到日志文件,因为它会将所有改变的行都写入日志。另外,binlog 日志文件在写入日志的时候会被锁住,如果数据太多可能会导致性能问题。可以添加参数 binlog_row_image=minimal 来减少这个缺点。
  • 如果一个确定的 UDF 产生了大量的 BLOB 数据,那么用 Row-Based 方式记录日志并恢复数据需要花费更多的时间。
  • For tables using the MyISAM storage engine, a stronger lock is required on the slave for INSERT statements when applying them as row-based events to the binary log than when applying them as statements. This means that concurrent inserts on MyISAM tables are not supported when using row-based replication

原文:
Replication Formats
Advantages and Disadvantages of Statement-Based and Row-Based Replication

    原文作者:高山流水
    原文地址: https://zhuanlan.zhihu.com/p/26977878
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞