I/O写入的原子性(Double Write)

要实现事务的原子性,先得考虑磁盘I/O的原子性。一个Log Block是512个字节。假设调用操作系统的一次Write,往磁盘上写入一个Log Block(512个字节),如果写到一半机器宕机后再重启,请问写入成功的字节数是0,还是[0,512]之间的任意一个数值?

这个问题的答案并不唯一,可能与操作系统底层和磁盘的机制有关,如果底层实现了 512个字节写入的原子性,上层就不需要做什么事情;否则,在上层就需要考虑这个问题。假设底层没有保证512个字节的原子性,可以通过在日志中加入checksum解决。通过checksum能判断出宕机之后重启,一个Log Block是否完整。如果不完整,就可以丢弃这个LogBlock,对日志来说,就是做截断操作.

除了日志写入有原子性问题,数据写入的原子性问题更大。一个Page有16KB,往磁盘上刷盘,如果刷到一半系统宕机再重启,请问这个 Page 是什么状态?在这种情况下,Page 既不是一个脏的Page,也不是一个干净的Page,而是一个损坏的Page。既然已经有Redo Log了,不能用Redo Log恢复这个Page吗?

因为Redo Log也恢复不了。因为Redo Log是Physiological Logging,里面只是一个对Page的修改的逻辑记录,Redo Log记录了哪个地方修改了,但不知道哪个地方损坏了。另外,即使为这个Page加了checksum,也只能判断出Page损坏了,只能丢弃,但无法恢复数据。有两个解决办法:

(1)让硬件支持16KB写入的原子性。要么写入0个字节,要么16KB全部成功。
(2)Double write。把16KB写入到一个临时的磁盘位置,写入成功后再拷贝到目标磁盘位置。

这样,即使目标磁盘位置的16KB因为宕机被损坏了,还可以用备份去恢复。

总结

  • 要实现事务的原子性,先得考虑磁盘I/O的原子性
  • 底层的原子性还是比较复杂的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值