公司最近开发的系统中偶尔会发生文件的损坏和目录的丢失,在调查的过程中发现使用自己不了解的东西总是要付出代价的。这里记录下调查的过程:
首先在测试环境了作了以下两个实验:
①长时间连续读写文件
②写文件中断电
实验①在15小时的连续读取中没有发生文件损坏及目录丢失、实验②20次的断电实验中也没有发生即存文件的损坏,这是唯一的一个好消息,说明这个问题发生的机率很低。
既然实验不行那就只能理论分析了,这次使用的存储介质时NAND Flash。Flash存储器 以页面(Page)的形式进行读写访问,它具有速度快、成本低等很多优点。但是由于制作工艺的原因 ,每个块的最大擦写次数是100万次,并且会发生位反转的问题。 NAND的供应商建议使用NAND闪存的时候,同时使用EDC/ECC算法。还好我们这次的读写芯片SM3251支持内置的ECC校验。
虽然ECC校验能搞纠正单bit的错误,但是当多个错误同时发生时就无能为力了。并且NAND flash的只读数据在访问100,000次后也容易发生异常。QNX为了解决这个问题设计了ETFS文件系统,此文件系统会跟踪NAND Flash每个数据块的读写次数,并提前作出处理。并且此系统能够延长NAND Flash的使用寿命。但是悲剧的是由于硬件设计问题导致此系统中并不能使用ETFS文件系统。
退而求其次,决定使用Power safe的QNX6文件系统,此文件系统号称使用了copy-on-write技术能够很好的预防在系统崩溃时发生的文件损坏问题。虽然QNX6文件系统不能解决NAND Flash的读写寿命问题,但是也如能够增强断电时的系统稳定性那也还说得过去。悲剧再次发生,咨询QNX公司的结论是QNX6文件系统的copy-on-write机能只支持硬盘而不支持Flash。已经没有第三种选择了,最终还是使用了QNX6文件系统。
但是问题总是要解决的啊,于是技术大拿出场。在多方求证后猜测文件的损坏是因为写文件过程中的断电,而导致的文件损坏。并且提出了对应的解决方案:取消QNX6文件系统中的缓存机制。其实在QNX中写文件并不会直接写入磁盘,而是会先缓存到内存中,并由OS决定何时真正何时写入磁盘(通常在5分钟内)。这不仅能够提升OS的读写效率还能减少磁盘中的文件碎片。这样看这是好事啊,干吗关啊?
QNX中的如果使用shutdown -b命令关闭系统就会发现,OS并不会切断电源。系统关闭了但是硬件还是保持启动状态。为了解决这个问题,我们系统在关闭时是直接调用CPU的断电指令的。这就导致OS的缓存写入磁盘的时机就可能发生在断电的时候,而如果不使用缓存,在系统关闭之前,系统中的文件操作肯定已经结束了,这就降低了系统中文件损坏的几率。
但是这种方案只是解决了正常运行中的文件损坏,而系统突然断电的文件损坏并没有解决。不过还好几率比较低。