发现问题

因为在常见的数据库中,持久化重做日志一般是先写日志再修改数据库,保证数据/操作不会丢失。所以看到redis的AOF日志的机制后,很困惑,

常见的有两种解释:

1.仅仅是因为,由于AOF文件会比较大,为了避免写入无效指令(错误指令),必须先做指令检查?如何检查,只能先执行了。因为语法级别检查并不能保证指令的有效性,比如删除一个不存在的key。而MySQL这种是因为它本身就维护了所有的表的信息,所以可以语法检查后过滤掉大部分无效指令直接记录日志,然后再执行。

2.Redis 的数据是存内存的,断电之后就丢了。Redis 的 AOF / RDB 相当于有一个把硬盘当内存的 slave。存储引擎数据是存硬盘的,断电之后,可能有脏数据,也可能没有,需要 redo log / undo log 来做原子 commit。保护 commit 的数据是不可能在 commit 之后写的。存储引擎的日志只保护 uncommitted data。

我个人觉得都有道理,可以综合考虑

1.如果有多条语句,执行了一条,然后停电了,就会导致出现脏数据,也无法进行完美的回滚,所以先记redo log/undo log来保证操作的原子性
而redis停电了内存里的数据就没有了,不会出现上述问题,所以可以先执行,再记AOF
2.如果redis也采取先写日志再操作的话,AOF日志中会出现很多无效/错误的命令记录,对本来就庞大的AOF文件来说简直是雪上加霜,我认为这是第一个原因。
3.另外一个原因我认为是,redis的事务比起mysql等数据库的事务机制来说,可以称为弱事务,事务中出现某一个错误也会继续执行,同时如果CAS发现事务执行过程中,数据被其他线程更改了,那么事务执行失败,redis也没有回滚。这样的事务,会出现很多没有修改成功数据命令。如果先写日志,同样会有很多无效命令。

————————————————
参考:
https://www.zhihu.com/question/342427472/answer/800699424