【问题标题】:Prevent data corruption防止数据损坏
【发布时间】:2014-09-17 08:55:25
【问题描述】:

我正在开发一个在 ARM9 上运行的嵌入式 linux。 文件系统是 ext4 类型(rw、sync、noatime、data=writeback) 我实现了一个进程,该进程以预写登录 (WAL) 模式写入/读取 SQLite3 数据库,并启用了不同步。发生断电时,我有大约两秒钟的时间通过同步和检查数据库来保存所有数据。但是,我仍然看到有时数据库被损坏,这在我的情况下真的不好。

我想为我的目的编写一个新的数据库引擎,以类似于 SQLite 的方式,其中数据库将保存在一个文件中。但是在这种情况下,我正在考虑将标头数据写入一个扇区,其余数据至少在两个扇区之后,因此数据库的大小会更大但是在写入数据时,它不会破坏标头文件,它包含索引等。这样,只有最后一个数据会被损坏,而不是所有文件,就像 SQLite 的行为一样。

我的问题是我的方法是否正确?

【问题讨论】:

  • 实现自己的数据库引擎对我来说听起来有点矫枉过正。所有严肃的数据库系统都应该提供数据一致性,包括 SQLite。您没有提及有关您正在使用的文件系统和硬件及其配置(日志记录、写入缓存等)的详细信息。也许您应该先寻找当前设置的实际问题?
  • 我更新了我的问题 - 提供了一些文件系统信息。也许这是矫枉过正,但我​​必须建立一个强大的数据库。不同之处在于,当我的设计中数据损坏时,保存元数据的标头(仅在创建 DB 文件时写入一次)不会损坏,因此 DB 仍然是可读的。
  • 为什么要检查数据库?不。无论如何,如果您使用的闪存存储在断电期间进行某些写入时会损坏 不相关 扇区,那么您无能为力。
  • 是的,我使用的是 SD 卡,而 SQLite 的问题是,当数据损坏时,我无法从数据库中读取任何内容,并且所有数据库都丢失了(而不是只是已写入的最新数据)。此外,每当设备检测到断电时,我都会手动启动检查点。

标签: linux database sqlite corruption wal


【解决方案1】:

你可以使用ping pong technique

在乒乓球技术中,您使用 2 个单独的文件并交替写入一个和另一个。如果在最坏的情况下发生断电,您最多只有 1 个损坏的文件,您可以安全地使用另一个。在最好的情况下,它们都没有损坏,您可以继续使用最新的。

如果您使用散列函数或其他 CRC 方案,很容易检测到损坏的文件

显然,这种方案不会让您免于写缓存或其他可能在后台工作的磁盘缓存机制。

或者,您可以使用具有独立数据完整性保护功能的日志文件系统

请注意,乒乓球和日志方案只能确保数据完整性。数据丢失仍然可能发生。数据完整性和数据丢失是完全不同的两件事

【讨论】:

  • 问题是,如果我将数据写入文件的扇区甚至不靠近包含数据库文件的索引和元数据的标题,为什么应该永远丢失数据发生?我从不写入标题,因此我唯一可以丢失的数据是已添加到 DB 文件中的最新数据。
  • 这很好,只要您有一种强有力的方法来区分“正确”数据和部分数据。即使您的系统在完全关闭之前有 2 秒的时间,一个块也可能被部分写入磁盘。您必须拒绝部分区块,因此您需要一种方法来检测它们
  • 是的,写入文件的每个数据块都经过校验和,并在其末尾添加签名。
猜你喜欢
  • 2021-09-20
  • 1970-01-01
  • 2014-06-03
  • 2014-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-26
相关资源
最近更新 更多