mysql 配置每次事务 commit binlog 都写磁盘感觉也不会丢数据,为什么要使用 redo log 一块保证 crash safe 呢?仅仅用 binlog 不可以吗
1
msg7086 2018-11-26 09:27:19 +08:00
我刚刚随便谷歌了一下,看到不少文章说这个的。你也可以试试看。
简单说,binlog 发生在 redolog 之后。 |
2
cc959798 OP @msg7086 是不少,我也看了一些,但是可能理解的都不太对,binlog 发生在后面这个我也知道,但是就是感觉没有 redo 也能保持不丢数据,只是不能保证未提交到事务不能恢复,但是感觉未提交到事务不恢复就不恢复呗,反正未提交
|
3
opennet 2018-11-26 10:14:14 +08:00
|
4
monsterxx03 2018-11-26 10:24:37 +08:00
楼主应该是认为 MySQL 每次写入数据的时候直接写入磁盘(ibd 文件), 但实际上写的是 WAL(write ahead log), 然后客户端就收到成功的返回了, 因为数据真正落地是随机写, 写 WAL 是顺序写, 要快得多. binlog 的生成应该在数据正真落地之后.
crash 重启后, ibd 文件不一定是最新的, 需要用 WAL 里的 redo log 来恢复数据. |
5
cc959798 OP @monsterxx03 不是,我是说写 log,binlog 也是 log,也能恢复数据不是吗?为什么还需要 redo log 来恢复数据,仅仅是为了恢复未提交的事务吗
|
6
cc959798 OP @opennet 看过了,但是没说为什么必须要用 redo log 和 binlog 结合方式来恢复数据,我觉得用 binlog 也是可以的
|
7
ebony0319 2018-11-26 12:39:36 +08:00 via Android
先写 redo log 后写 binlog。假设在 redo log 写完,binlog 还没有写完的时候,MySQL 进程异常重启。由于我们前面说过的,redo log 写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行 c 的值是 1。
但是由于 binlog 没写完就 crash 了,这时候 binlog 里面就没有记录这个语句。因此,之后备份日志的时候,存起来的 binlog 里面就没有这条语句。 然后你会发现,如果需要用这个 binlog 来恢复临时库的话,由于这个语句的 binlog 丢失,这个临时库就会少了这一次更新,恢复出来的这一行 c 的值就是 0,与原库的值不同。 先写 binlog 后写 redo log。如果在 binlog 写完之后 crash,由于 redo log 还没写,崩溃恢复以后这个事务无效,所以这一行 c 的值是 0。但是 binlog 里面已经记录了“把 c 从 0 改成 1 ”这个日志。所以,在之后用 binlog 来恢复的时候就多了一个事务出来,恢复出来的这先写 redo log 后写 binlog。假设在 redo log 写完,binlog 还没有写完的时候,MySQL 进程异常重启。由于我们前面说过的,redo log 写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行 c 的值是 1。 但是由于 binlog 没写完就 crash 了,这时候 binlog 里面就没有记录这个语句。因此,之后备份日志的时候,存起来的 binlog 里面就没有这条语句。 然后你会发现,如果需要用这个 binlog 来恢复临时库的话,由于这个语句的 binlog 丢失,这个临时库就会少了这一次更新,恢复出来的这一行 c 的值就是 0,与原库的值不同。 先写 binlog 后写 redo log。如果在 binlog 写完之后 crash,由于 redo log 还没写,崩溃恢复以后这个事务无效,所以这一行 c 的值是 0。但是 binlog 里面已经记录了“把 c 从 0 改成 1 ”这个日志。所以,在之后用 binlog 来恢复的时候就多了一个事务出来,恢复出来的这先写 redo log 后写 binlog。假设在 redo log 写完,binlog 还没有写完的时候,MySQL 进程异常重启。由于我们前面说过的,redo log 写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行 c 的值是 1。 但是由于 binlog 没写完就 crash 了,这时候 binlog 里面就没有记录这个语句。因此,之后备份日志的时候,存起来的 binlog 里面就没有这条语句。 然后你会发现,如果需要用这个 binlog 来恢复临时库的话,由于这个语句的 binlog 丢失,这个临时库就会少了这一次更新,恢复出来的这一行 c 的值就是 0,与原库的值不同。 先写 binlog 后写 redo log。如果在 binlog 写完之后 crash,由于 redo log 还没写,崩溃恢复以后这个事务无效,所以这一行 c 的值是 0。但是 binlog 里面已经记录了“把 c 从 0 改成 1 ”这个日志。所以,在之后用 binlog 来恢复的时候就多了一个事务出来,恢复出来的这一行 c 的值就是 1,与原库的值不同。 |
8
ebony0319 2018-11-26 12:40:30 +08:00 via Android
我取的也是 林晓斌 的原话,已经解释非常清楚了。
|
9
cc959798 OP @ebony0319 大佬你复制多了,这些我也是看明白了,我的意思 如果把 binlog 放在事务 commit 之前写入的话,这样也可以保证数据不丢失,比如 log 写了,然后断电,这个时候虽然没 commit,但是 commit 是最后一步了,也可以算作已经 commit 了,这样可以恢复数据,如果是 log 写之前就断电,ccommit 还没提交,就不会有新的这条数据,也会是合理的
换句话说,我们不写日志,commit 时 直接写数据到磁盘(虽然是有性能问题),但是也是可以保证数据断电不丢失(除非磁盘坏了) |
10
GaryZ 2018-11-26 15:05:27 +08:00
我觉得是数据恢复的时候是否能保持一致性的问题吧
|
11
monsterxx03 2018-11-26 15:23:17 +08:00
@cc959798 大概明白你的意思了, MySQL 支持不只一种存储引擎, 各种不同的存储引擎都能开 binlog (用于获取 ongoing change, master/slave), 但 redo/undo log 是 innodb 专属的. 它们工作在不同层面上.
如果设计一个 innodb 专属的 MySQL, 的确可以只保留一种 log, 比如 aws 的 aurora db, master/slave 之间就是通过 redo log 同步的( 当然 binlog 也可以开) |
12
ebony0319 2018-11-26 16:19:02 +08:00 via Android
是不是可以这样理解。每种成功的概率是 0.9,那么两份备份失败的概率等于 1-0.1*0.1=0.99 ?
|
13
ebony0319 2018-11-26 16:20:54 +08:00 via Android
而且 redo log 是 Innodb 特有的。
|
14
cc959798 OP @monsterxx03 嗯嗯,这些都知道,redo 是在存储引擎层面的,但是就是奇怪,binlog 可以实现断电恢复,为什么还要加个 redo log
|
15
msg7086 2018-11-26 17:24:32 +08:00
binlog 没有 redo log 那么牛逼。
redo log 是事务边跑边写的,commit 的时候只要 mark 一下就行了。binlog 得要整个事务确定 commit 或者 rollback 才会一次性写入,可靠性哪有 redo log 高。 @ebony0319 你可以理解成 binlog 成功的概率是 0.8,而 redo log 成功的概率是 0.98 。因为有个 0.8 的 binlog 所以把 0.98 的 redo log 去掉是很得不偿失的。 |
16
cc959798 OP @ebony0319 仅仅是这样吗?如果 binlog 每次事务都写磁盘的话理论上数据也是不会丢失的,没写成功不让 commit,这样不就可以了。难道仅仅是因为存储引擎不能控制 binlog 或者说存储引擎不关心 binlog 而作的一种妥协?
|
17
monsterxx03 2018-11-26 17:52:27 +08:00
有点钻牛角尖了额, 你先做了个假设: 把 binlog 提前到 commit 之前写,然后就能用 binlog 来做 crash recover.
问题是目前 binlog 和 redo log 的实现格式完全不同(binlog 根据你需求可选三种呢). 刷盘机制也完全不同. 虽然我不了解这块代码的实现, 但工程上硬用 binlog 来实现 crash recovery 感觉是不行的.(你想想还有 semi sync 的同步方式呢, 同步这块相当复杂) binlog 的设计目的是为了让外部系统获取数据库内的数据变更,可以理解成一个 expose 的接口. redo 是 innodb 为了达成 acid, crash recovery 的一种内部实现手段. 存储引擎的确不能控制 binlog, 也不应该关心 binlog, 这不算妥协, 是 by design. |
18
monsterxx03 2018-11-26 18:01:04 +08:00
还有目前的 binlog 并不能实现断电恢复, binlog 可以做 point-in-time recovery 这个一般是写坏数据了用来修数据的.
|
19
cc959798 OP @monsterxx03 嗯嗯你这么说感觉也是有道理的
|
20
julyclyde 2018-11-27 09:57:00 +08:00
binlog 其实是个外挂式的东西
|