在写 wal 的实现的时候,不知道如何处理 append 数据时如果发生断电之类的故障如何保证数据安全,想知道如果发生这样的情况会是怎样的,可能是数据只写了一半?也不知道新写入数据时发生故障是否会影响之前写入的内容。我现在的实现是每个 LogEntry 加个 crc 校验字段,在读取数据时检验一下数据时用 crc 校验一下数据。
看了 etcd 的 wal 实现,好像如果发生这样的情况,扇区的情况是全 zero 。
大概流程就是校验一下 crc,不对就进入 isTornEntry 逻辑判断数据所在的扇区是否存在全 zero 的情况。
if err := rec.Validate(d.crc.Sum32()); err != nil {
if d.isTornEntry(data) {
return io.ErrUnexpectedEOF
}
return err
}
isTornEntry 函数的主要逻辑
// if any data for a sector chunk is all 0, it's a torn write
for _, sect := range chunks {
isZero := true
for _, v := range sect {
if v != 0 {
isZero = false
break
}
}
if isZero {
return true
}
}