免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5439 | 回复: 7
打印 上一主题 下一主题

[算法] 文件的断电可靠性保证 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-28 17:11 |只看该作者 |倒序浏览
文件的断电可靠性保证

author:bripengandre     Email:bripengandre@126.com



一.背景  
  最近参与开发的一个嵌入式设备对系统的稳定性、可靠性和可恢复性提出了较高的要求。特别地,有这些问题要考虑:当系统在更新关键文件(如内核)时突然断电,能否让系统重启后恢复到断电前瞬间的状态?如果不能恢复到断电前瞬间的状态,那能否恢复到最近的一次正确配置,让系统不致于死机?


二.问题的提出   
  可靠性和可恢复性难以保证的一个原因是,在一般的操作系统用户空间写文件到存储设备,要经历如下的一个过程:用户空间文件缓冲(如果用了标准IO)-->内核文件缓冲-->内核输出到存储设备的输出缓冲-->存储设备,只要全过程中的任一环节出了问题,可靠性等就难以保证。上述各环节彼此之间是非阻塞的,前一环节不必等后一环节完成就可成功返回。例如fwrite并fflush了文件内容到了内核文件缓冲,并不能保证这些内容已进入了内核的输出缓冲,按照APUE上的说法,为了提高读写效率,内核文件缓冲到内核输出缓冲一般要延迟(一般是30s),这是一个延迟写的过程。

三.问题的解决
    分析市面上已有的设备及他人的文章,发现有如下几种策略(策略可组合运用)。

3.1 可靠性保证(保证文件在断电前后一致)
    严格的可靠性保证。这只能通过硬件保证,例如提供一个UPS电源(不间断电源),系统突然断电时,UPS提供续电并给操作系统一个中断,让操作系统启动一个清理服务例程来保证可靠性。
  准可靠性保证。一般的商用嵌入式系统因成本等原因是不可能备有UPS电源的,这就只能通过软件来近似保证了,原则上只要减少文件的更新所用的时间,根据随机性原理,更新过程中突然断电的概率就会变小。对于小文件,更新速度的最大瓶颈一般在内核文件缓冲到内核输出缓冲这一步,所以一般都在fflush文件后,就调用fsync来加速文件输出到内核输出缓冲,当然这些是以牺牲效率为代价的。

3.2 可恢复性(出错时能回滚到一个正确的中间状态)
    硬件复位。提供一个硬件按钮,供复位到出厂配置或最近的一次配置,如很多电子词典就有一个复位孔。硬件复位的优点是任何时候都能“一键还原”,缺点是实现比较难。考虑一个嵌入式linux的启动过程,有如下几步:bootloader(相当于PC上的BIOS+GRUB)-->内核-->应用程序一个完整的硬件复位应能做到对这三步的硬复位,即必须校验上述三者的正确性,然后作出相应的响应,例如在bootloader层或内核层出了问题,我们执行文件恢复操作就得在NONOS下进行的,即实现裸文件操作(raw ops)。所幸的是,很多时候,我们一般只会更新应用程序,这个时候在强大的操作系统下,我们可以轻松地为所欲为。
   软件复位。软硬件复位的区别是复位触发点不同,软件复位的触发点是软件自检,而硬复位的触发点一般是硬件中断。
对于无人看管的设备,硬件中断无从触发,这时候就必须有软件自检复位了。还是以前面提到的嵌入式linux启动过程为例只要这三者在自己启动时都进行自检如果自检出错就回滚到冗余备份的老版本(对存储有点小挑战)则可恢复性就几乎perfect了至于如何自检最简单的就是文件完整性和安全性保证了这些在信息安全里面讲的多了实际中,一般只检查完整性可以对每个文件生成一个校验文件(如md5或pgp)自检时发现新文件校验不正确使用备份的老文件就可以了当然了这里有个鸡和蛋的问题了自检的启动也是代码过程如果自检代码都破坏了...振作一点,要做到自检代码不破坏让它只读就行了例如在应用程序层你完全可以写一个永远正确并永不更新的只读程序这个程序用来启动其它可能会被更新的应用程序

   最后本文只是个人的一点看法欢迎大家提出其它好的建议

[ 本帖最后由 bripengandre 于 2009-11-28 19:24 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-11-28 18:07 |只看该作者
CPU都不运转了,一条指令都跑不动,还算法呢。
最好的解决方法,加不断电的备用电源。

论坛徽章:
0
3 [报告]
发表于 2009-11-28 19:29 |只看该作者
原帖由 prolj 于 2009-11-28 18:07 发表
CPU都不运转了,一条指令都跑不动,还算法呢。
最好的解决方法,加不断电的备用电源。

你可以把算法广义地理解为策略或方法。。。

论坛徽章:
0
4 [报告]
发表于 2009-11-28 19:34 |只看该作者

回复 #3 bripengandre 的帖子

说实话,yaffs2基本上用journaling把问题给解决了。
当然,flash的应用有不少局限性,如果要挂接大存储,完全可以用NFS。

论坛徽章:
0
5 [报告]
发表于 2009-11-28 19:38 |只看该作者
恩,我理解,广义的,哲学的,抽象的,可是这些虚的玩意儿能给我带来一毛钱利益?麻烦来点儿牛B的代码,我也改改EXT文件系统,万一EXT6是我写出来的,我就发达了,比这种虚无缥缈的东西好多了。

论坛徽章:
0
6 [报告]
发表于 2009-11-29 00:27 |只看该作者
原帖由 langue 于 2009-11-28 19:34 发表
说实话,yaffs2基本上用journaling把问题给解决了。
当然,flash的应用有不少局限性,如果要挂接大存储,完全可以用NFS。

jffs2等日志文件系统在断电可靠性方面做了功夫,我不是很了解,欢迎指教。
但文件系统起来之前的内核等,或应用层上还是有做些工作的可能。

论坛徽章:
0
7 [报告]
发表于 2009-11-29 01:30 |只看该作者

回复 #1 bripengandre 的帖子

可以设计一种模式,每当要更新重要文件进入这种模式下。
模式:直接向并发向两个硬件存储器上写。一个用于恢复用另一个就修改的文件
写两个模块一个开机检测模块、一个写模块。
写模块:若写完向一个硬件写上标志。
检测模块:开机检测这个硬件标志 ,然后回滚写操作 恢复到原来系统

                                  初学者之言,若想法愚蠢,请当笑话看之

[ 本帖最后由 kanhfshiys 于 2009-11-29 01:32 编辑 ]

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
8 [报告]
发表于 2009-11-29 17:21 |只看该作者
原帖由 bripengandre 于 2009-11-28 17:11 发表
最近参与开发的一个嵌入式设备对系统的稳定性、可靠性和可恢复性提出了较高的要求。特别地,有这些问题要考虑:当系统在更新关键文件(如内核)时突然断电,能否让系统重启后恢复到断电前瞬间的状态?如果不能恢复到断电前瞬间的状态,那能否恢复到最近的一次正确配置,让系统不致于死机?

这是完全可以做到的,不过需要操作系统支持,就是需要写在内核。
最早是在INFORMIX数据库里完全实现了,采用物理日志+逻辑日志的算法。

基本思想是写前先保存。
在写某一块数据前,先将其保存在物理日志区。然后新数据写入该块,所有事务的一致写完成后,清除物理日志。

如果新开机,发现有物理日志,则恢复之,恢复成功,清除物理日志。

[ 本帖最后由 yulihua49 于 2009-11-29 17:25 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP