向文件追加数据的时候发生断电之类的故障,会怎样?

2021-03-25 23:39:21 +08:00
 zzkde

在写 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
    }
}

etcd 的 wal 源码

1162 次点击
所在节点    问与答
5 条回复
liprais
2021-03-26 00:06:36 +08:00
"The other consideration is to make sure that corrupted log files are detected while reading the log. To handle this, log entries are generally written with the CRC records, which then can be validated when the files are read. "
https://martinfowler.com/articles/patterns-of-distributed-systems/wal.html
你的实现看起来没啥问题
wakzz
2021-03-26 09:07:10 +08:00
你这个其实是在问数据落盘的方案,现在的主流方式有:
1. Double Write
2. Shadow Paging
3. Trans Log
4. 每次全量写(Redis 的 RDB)
wakzz
2021-03-26 09:11:05 +08:00
程序应该自己保证数据落盘后文件完整性,就算写入中途突然断电中断导致数据页损坏,也可以通过应用本身的逻辑处理,或恢复成正确的旧数据,或接着断电前继续写新数据,而不会出现数据错乱的情况。
zzkde
2021-03-26 12:50:24 +08:00
@wakzz Double Write 和 Shadow Paging 关注的是数据页的写入,Trans Log 就是 wal 。无法解决我当前的疑惑啊
@liprais 赞!这篇文章刚好我也看了,但是里面没有更多的实现细节
wakzz
2021-03-26 13:56:48 +08:00
@zzkde 常见的是 Trans Log 和 Double Write 组合,数据更新时先添加 Trans Log,如果 Trans Log 写入失败则操作失败,每一条 Trans Log 都有完整校验,应用重启恢复读取 Trans Log 时完整校验没过 的 log 直接忽略。
然后数据写入通过 Double Write 方式,Double Write 是写两次,如果是第二次写失败可以通过第一次写的数据恢复;如果是第一次写失败,则可以通过 Trans Log 和原本的数据副本恢复。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/765212

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX