青训营|MySQL日志系统

71 阅读4分钟

首先介绍两个日志的基本概念,一个是物理操作,一个是逻辑操作。

  • 物理操作

    物理操作是对数据库底层数据存储结构的操作,即对数据在物理存储设备上的读写操作,例如读取和写入具体的数据块、页或者记录等。物理操作直接访问存储设备,包括对设备的读取、写入、删除操作等,因此它对应着实际的存储结构。 因为redolog是Innodb中特有的日志,又因为存储引擎在最底层,所以redolog是物理操作。

  • 逻辑操作

    逻辑操作是对数据库中对象的操作,例如对表中数据的增删改查等操作,它是基于用户或应用程序想要执行的实际操作进行的操作。逻辑操作是以SQL语言的形式体现的,根据不同的SQL语句可以进行增删改查等逻辑操作,而不考虑数据的存储细节和实际操作过程。因为binlog是mysql中自带的,所以在上层,只能进行逻辑操作的记录。

接下来来讲两个日志,一个是redolog,一个是binlog。

  • redolog(主要作用是crash-safe)

    redolog出现的目的是完成事物的一致性,当事务进行到一半的时候mysql突然崩溃了,redolog可以进行回滚操作,它本身是以二进制的方式存储的。还有一个持久化的目的,因为每次想把操作持久化都要进行磁盘的读写,但是磁盘读写太慢了,所以先在内存记录下来,当系统不忙的时候在写到磁盘上去。其实就是MySQL里经常说到的WAL技术,WAL的全称是Write-Ahead Logging。因为redolog是物理操作,所以存的都是结果如何变更,不会存具体的逻辑。它的存储方式如下图:

    checkpoint表示从哪里开始,write pos表示在哪里结束

  • binlog(主要作用是归档,即回到某一个时间点的数据库状态)

    底层使用二进制存储的语句逻辑,加入想回到中午那时候的数据库,就需要找到中午之前最近的全局备份,然后执行binlog到中午即可。

    常见的 binlog 格式有三种:statement、row 和 mixed,不同格式的 binlog 会记录不同粒度的信息。

    • statement 格式是最常见的 binlog 格式,它记录的是 SQL 语句的执行信息。也就是说,如果一个 SQL 语句要修改多行数据,那它只需要记录这条语句本身,而不需要记录每行数据的修改情况。这种格式下日志量小,但是存在一定的不一致性。
    • row 格式记录的是每一行数据修改的详细情况,一条修改命令会被具体记录为几条将要修改数据的语句。这种格式下数据更为详细,但是日志量较大。
    • mixed 格式在 statement 和 row 格式之间切换,刚开始以 statement 方式记录日志,当出现不支持语句级别的操作时,会自动转化为 row 格式记录。mixed 格式将 statement 和 row 格式的优点结合起来,同时也存在对应的缺点。

这两个日志相结合,使用的时候需要保证一致性,如果在两个日志中间crash了,保证不了一致性,所以引入了一个类似事务的操作,如下图:

将redo log的写入拆成了两个步骤:prepare和commit,这就是"两阶段提交"。

redo log用于保证crash-safe能力。innodb_flush_log_at_trx_commit这个参数设置成1的时候,表示每次事务的redo log都直接持久化到磁盘。这个参数我建议你设置成1,这样可以保证MySQL异常重启之后数据不丢失。

sync_binlog这个参数设置成1的时候,表示每次事务的binlog都持久化到磁盘。这个参数我也建议你设置成1,这样可以保证MySQL异常重启之后binlog不丢失。