Python 的轻量级崩溃恢复

1 投票
5 回答
1490 浏览
提问于 2025-04-15 15:32

我该如何处理我的程序的轻量级崩溃恢复呢?

我有一个用Python写的程序,它会运行一些测试案例,结果会存储在一个字典里,这个字典就像一个缓存。如果我能把每个添加到字典里的项目保存下来(然后再恢复),那么我只需重新运行程序,缓存就能提供合适的崩溃恢复。

  1. 你可以假设字典里的键和值都可以很容易地转换成字符串,比如用str函数或者pickle模块
  2. 我希望这个方法能在不同的平台上都能用——至少要和Python一样跨平台。
  3. 我不想简单地把每个值写到文件里,因为在写文件的时候程序可能会崩溃。
  4. 更新:我想要的是一个轻量级的模块,所以不考虑使用数据库管理系统。
  5. 更新:Alex说得对,我其实不需要在写文件的时候保护程序不崩溃,但有些情况下我希望能够手动终止程序,并且能恢复到一个可用的状态。
  6. 更新:下面添加了一个使用标准输入的非常有限的解决方案。

5 个回答

1

一种可能的方法是创建几个小文件,每个文件代表你想要保存的状态的一部分,并且每个文件的最后一行或数据都有一个校验和或标签,表示这个文件是完整的(就在文件关闭之前)。

如果校验和或标签是正确的,那么其他的数据就可以认为是有效的。不过程序需要找到所有这些文件,打开并读取它们,然后利用你提供的元数据(可能在文件的头部或文件名中)来判断哪些文件代表了最新的完整状态(或者说是检查点),这样你就可以继续处理了。

如果不了解你正在处理的数据的具体情况,就很难给出更详细的建议。

当然,你可以使用文件,也可以使用数据库管理系统(DBMS),这两者都差不多。任何一个不错的数据库系统(比如PostgreSQL、MySQL,只要你使用合适的存储后端)都能保证ACID特性和事务支持。因此,你读取的数据应该始终与你在数据库结构中设置的约束条件一致,或者与处理过的事务(比如开始、提交、回滚)一致。

将你的序列化数据放到数据库管理系统中的一个可能好处是,你可以把数据库系统放在一个独立的系统上,这样它就不太可能在同一时间遭遇和你的测试主机一样的故障。

1

pickle模块可以把对象保存到文件里,也可以从文件中加载这些对象。

http://docs.python.org/library/pickle.html

2

没有什么好的方法可以防止“你的程序在写入检查点到文件时崩溃”,但你为什么要这么担心呢?在这个时候,除了“把检查点保存到文件”之外,你的程序还在做什么呢?这些事情可能也会导致程序崩溃!

在Python中,使用pickle(或者cPickle)来保存数据是很方便的,它可以把你的键和值转换成字符串。不过,这只是把数据变成字符串而已。对于保存键值对(变成字符串后),没有什么比直接把数据追加到文件里更安全的了(如果你的程序崩溃得比正常情况频繁得多,就不要用pickle保存到文件了,正如你所说的那样)。

如果你的环境因为某种原因非常容易崩溃(比如硬件很便宜?),那你只需要确保在写入文件后关闭它(如果操作系统也容易崩溃,就再调用一下fflush),然后再重新打开文件进行追加。这样,最糟糕的情况就是你最后一次追加的数据可能不完整(因为在写入过程中崩溃了)——然后你只需要处理那个不完整记录引发的异常,重新做那些没有保存的事情(因为崩溃导致没有完成,或者虽然完成了但没有完全保存,最终结果是一样的)。

如果你可以选择把检查点保存到数据库引擎(而不是仅仅保存到文件),那就认真考虑一下这个选项!数据库引擎会保留事务日志,并确保ACID特性,这样会让你的应用程序编程变得更简单,只要你能依赖这个!

撰写回答