摘要:
记录关于事务及数据安全的思考, 虽说持久性和一致性是事务的特征, 不过将数据安全再摘出来还是有好处。
事务中对于数据安全的实现的策略:
一. undo日志
- 记录元素修改前的数据
- 由于记录旧的数据, 所以可以用其数据完成多版本控制
- 必须要在元素修改前,将旧元素写到磁盘的undo日志
- 当事务commit到磁盘时后, 则将undo日志中的记录做标记
- 利用undo日志恢复数据
- 当遇到没有commit标记的记录时,则作旧元素恢复
- 当存在commit标记时, 则跳过
- 可以看下利用undo日志的磁盘io
- 事务开始时做记录
- 元素修改前做undo元素记录
- 事务提交后做undo事务标记
- undo日志涉及大量的磁盘io
二. redo日志
- innodb中使用redo日志这个名字, 一些数据更直接的就称呼为WAL, write append log, 例如rocksdb, influxdb, duckdb
- redo日志中记录事务中元素要修改后的新值
- 由于只需要记录元素的修改, 磁盘IO相比undo日志要少
- 事务开始时记录事务信息
- 元素在内存缓冲区中修改后, 立即写入redo日志的元素变更
- 当事务commit时, 在redo日志中做commit标记
- 整个过程都不要求事务系统做磁盘IO持久化, 仅需要写redo日志
- 但是使用redo日志有限制条件,
- 当事务开始前, 元素的旧值必须已经通过事务系统持久化到磁盘
- 也就是说,每一个新的事务开始写redo日志的前提, 是该元素的旧值可以从磁盘中恢复
- 这也很好理解, 利用redo进行恢复, 是利用新值进行覆盖, 如果redo日志中没有, 那么就说明事务系统的持久化数据可信
- 对应的, 如果redo日志中存在commit, 那么必须进行新值覆盖
三. 可参考的数据安全的实现
- duckdb的WAL层
- innodb的undo log和redo log
- percona-mysql的rocksdb引擎的事务实现