中电网移动|移动中电网|高清图滚动区

ZLG嵌入式笔记 :丢数据比丢钱还让人头疼

在产品运行过程中,数据丢失是常见的问题,尤其在频繁写入数据的场景中。本文将分析数据丢失的原因,并从硬件、系统和软件优化等方面提供解决思路,帮助提升数据安全性和系统稳定性。

丢数据情形

丢数据的问题一般发生在产品运行现场有频繁数据写入的情形,特别是在使用了数据库的时候。一般有以下表现:

  1. • 轻微表现:数据库最新记录的数据项无故丢失;

  2. • 比较严重情况:较多记录项数据丢失;

  3. • 严重情形:文件名丢失或者乱码;

  4. • 非常严重情形:系统文件丢失,或者整个/opt分区无数据。

丢数据原因及解决思路

丢数据的表现非常复杂,还有更多其它表现。究其原因,不外乎硬件方面、驱动层面以及应用程序设计等几个方面。

像硬件部分,电源是重中之重,驱动层面的话,稳健可靠的驱动程序是至关重要的。但仅仅做好这两方面,如果应用软件没进行系统优化或者数据处理优化,同样也会带来丢数据的风险。下面分别从这几方面来做一些阐述。

1. 基本思路:硬件设计+系统设计+软件优化

稳定可靠的电源,掉电检测电路,后备电源,系统设计的掉电检测设计,应用程序对掉电的响应,以及平时的数据冗余备份等措施。

2. 解决现场丢数据的问题,需要从硬件、驱动、应用设计多方面入手才能妥善解决

2.1 选择合适的文件系统

不同的存储介质需要适配不同的文件系统,在嵌入式设备中常用的存储器是NAND Flash和eMMC。

适合NAND Flash的文件系统是UBIFS和YAFFS2。UBIFS和YAFFS2的不同之处在于它们的存储方式、性能、垃圾回收机制和应用场景:

2.1.1 存储方式

UBIFS是基于块存储的,而YAFFS2是基于页存储的。YAFFS2将文件数据划分为固定大小的页,可以更好地适应NAND Flash的物理特性,减少存储空间的浪费,提高了存储空间的利用率。而块的大小通常比页大,这意味着UBIFS可以更有效地管理存储空间。与YAFFS2相比,UBIFS使用的块更大,从而减少了存储空间的浪费和碎片化的可能性。另一方面,UBIFS的块存储机制可以适应不同大小和容量的闪存设备,并能根据实际需求进行动态调整,具备更好的可扩展性和灵活性。

2.1.2 性能方面

UBIFS支持write-back,其写入的数据会被cache,直到有必要写入时才写到flash,可以大大地降低分散小区块数量并提高I/O效率。YAFFS2则是实时写入,这会影响一部分I/O性能,但由于页是YAFFS2最小的存储单位,所以YAFFS2可以迅速定位到特定的页,并只读取或写入所需的数据,而不需要处理整个文件。这种局部性的访问方式可以减少不必要的读取和写入操作。

2.13 垃圾回收机制方面

UBIFS是基于日志型的垃圾回收,日志的垃圾回收机制提供了一种原子性和一致性的保证。所有的文件更新操作首先会被记录到日志区域,而不是直接写入到主存储区域。只有当这些更新操作被成功记录到日志后,才会进行实际的数据更新。这种方式确保了在更新操作过程中出现意外中断或系统崩溃时,文件系统能够恢复到一致的状态。

其次,日志型的垃圾回收机制实际的数据更新是异步进行的,即不会每次都同步到flash,因此写操作的延迟被显著降低,同时也减少了闪存擦除的次数。这种设计使得UBIFS在面对大量的写操作时能够保持较高的性能。

YAFFS2使用段式的垃圾回收。当文件系统中的数据被修改或删除时,会标记相应的段为无效或可回收。段式回收的过程包括扫描这些无效的段,并将其中的数据进行擦除和回收,以便重新利用这些存储空间。

段式回收的好处是可以批量处理无效数据,提高垃圾回收的效率。相对于基于页的回收机制,段式回收减少了对闪存的频繁擦除操作,从而延长了闪存的使用寿命。此外,由于回收操作是在段的级别上进行的,它能够更有效地管理存储空间,减少了存储碎片化的可能性。

2.1.4 在应用场景上

UBIFS更适合大容量存储系统,而YAFFS2更适用于中小容量的NAND Flash存储设备。

适合eMMC的文件系统是FAT32和Ext4。其差异主要体现在兼容性、性能、安全性和磁盘空间利用这几个方面:

选择哪个文件系统取决于具体的应用场景和需求。

对于NAND Flash,如果存储器容量较大且能保证设备长期运行的情况下,UBIFS是个很好的选择。如果设备需要经常读写文件,且存在偶发性断电,则YAFFS2更合适。

对于eMMC来说,如果需要广泛的兼容性和简单的操作,FAT32可能是一个不错的选择。然而,在需要更高的性能、安全性和稳定性时,EXT4可能更适合。

2.2 系统挂载方式

在Linux系统下必须先挂载对应设备,然后才能被访问,挂载方式有很多,包括同步挂载(sync)、异步挂载(async)、只读挂载(ro)、读写挂载(rw)等,不同的挂载方式会直接影响系统的功能与性能:

Linux在使用mount命令挂载时,如果不指定挂载参数,其默认的挂载方式为异步可读写方式,如果需要使用其它挂载方式,可以通过“-o”参数指定,例如:

[root@user ~]# mount -o ro /dev/mmcblk0p2 /mnt //只读挂载

如果修改挂载方式,可以使用“-o remount”来指定,多个挂载参数可以用“,”隔开:

[root@user ~]# mount -o remount,rw /dev/mmcblk0p2 /mnt //重新挂载为可读写方式

如果需要修改系统的自动挂载方式,可以通过在/etc/fstab文件下添加对分区的挂载描述,fstab文件内容如下:

[root@user:~]# cat /etc/fstab #stock fstab - you probably want to override this with a machine specific one/dev/root / auto defaults 1 1proc /proc proc defaults 0 0devpts /dev/pts devpts mode=0620,gid=5 0 0usbdevfs /proc/bus/usb usbdevfs noauto 0 0tmpfs /run tmpfs mode=0755,nodev,nosuid,strictatime 0 0tmpfs /var/volatile tmpfs defaults,size=50M 0 0tmpfs /media/ram tmpfs defaults,size=16M 0 0

其中,第4列为对应分区的挂载方式(类似于mount -o),可以通过修改该列来实现不同挂载方式。

猜你喜欢
中电网移动|移动中电网|频道导航区