转载自华为服务支持的文件系统损坏类问题
整机掉电、存储断链和系统panic是常见且不可避免的三种异常场景。需要考虑文件系统的元数据、数据是否会因此损坏。针对EXT4文件系统,能够保证文件系统的一致性,但无法保证正在修改的文件数据一致。
JBD2日志
在掉电、panic等异常场景下,导致文件系统损坏的根本原因在于写文件不是原子操作,因为写文件涉及的不仅仅是用户数据,还涉及元数据(metadata)包括 Superblock、inode bitmap、inode、data block bitmap等,所以写操作无法一步完成,如果其中任何一个步骤被打断,就会造成数据的不一致或损坏。Linux 中的日志块设备(JBD,Journal Block Device )可以解决这个问题。
日志文件系统(EXT4/xfs等),在进行写操作之前,把即将进行的各个步骤(称为transaction)事先记录下来,保存在文件系统上单独开辟的一块空间上,这就是所谓的日志。日志保存成功之后才进行真正的写操作、把文件系统的元数据和用户数据写进硬盘(称为checkpoint)。
这样万一写操作的过程中掉电,下次挂载文件系统之前把保存好的日志重新执行一遍就行了(术语叫做replay),避免了前述的数据损坏场景。EXT4文件系统的日志叫做JBD2。
JBD2日志格式
EXT4文件系统,专门在磁盘上划了一块区域,用于存放journal日志。JBD2日志里面有文件系统的metadata。日志格式如下:

如上图, 每一条日志都有descriptor block 和commit block两个块,表示一条日志的开始和结束。其中descriptor block记录了实际磁盘块与日志块的对应关系。在descriptor block和commit block中间,就是元数据日志。
三种日志处理模式
EXT4有三种日志处理模式:
1) journal最安全但性能最差(metadata journal --> data --> metadata)
data=journal模式提供了完全的数据块和元数据快的日志,所有的数据都会被先写入到日志里,然后再写入磁盘(掉电非易失存储介质)上。在文件系统崩溃的时候,日志就可以进行reply,把数据和元数据带回到一个一致性的状态,journal模式性能是三种模式中最低的,因为所有的数据都需要日志来记录。
2) ordered(*)数据先落盘,再做元数据的日志 (data --> metadata journal --> metadata)
在data=ordered模式下,ext4文件系统只提供元数据的日志,但它逻辑上将与数据更改相关的元数据信息与数据块分组到一个称为事务的单元中。当需要把元数据写入到磁盘上的时候,与元数据关联的数据块会首先写入。也就是数据先落盘,再做元数据的日志。一般情况下,这种模式的性能会略逊色于 writeback 但是比 journal 模式要快的多。
3) writeback 仅做元数据的日志,性能最优(data和metadata journal不分先后)
在data=writeback模式下,当元数据提交到日志后,data可以直接被提交到磁盘。即会做元数据日志,数据不做日志,并且不保证数据比元数据先落盘。writeback是ext4提供的性能最好的模式。
备注:数据,日志,元数据这三部分内容的落盘顺序是保证文件系统可靠性的生命。
JBD2保护文件系统完整性的原理
1) ordered模式下,只记录metadata的journal日志。落盘顺序为: data --> metadata journal --> metadata。
2) 系统掉电或者panic,OS缓存丢失,可能导致文件元数据、数据没有落到实际的磁盘区域内。重启后,挂载磁盘时,系统会将JBD2日志区里面的元数据,反刷到对应磁盘区域(JBD2日志重演)。所以,只要日志数据正确,就能保证ext4文件系统格式不被破坏。(文件的数据部分无法保证)
3) 掉电时,JBD2日志也有可能没有落盘,或者落了一半:
a) JBD2日志没有落盘:由于ordered模式下,journal metadata先于metadata落盘,所以此时metadata也没有更新,并不影响文件系统完整性。
b) JBD2日志落了一部分:descriptor block 和 commit block两个块必须都存在,才会作为一条有效记录。如果没有commit,则该记录废弃。
c) 一个JBD2事务作为一个原子操作,此时即使丢失整条日志,并不影响文件系统完整性。
总结
通过本文大致了解JBD日志块设备保证文件系统完整性的原理。
数据,日志,元数据这三部分内容的落盘顺序是保证文件系统可靠性的生命。
还有很多不明白的地方,请路过到大神指正,求教。
待思考的几个问题,备忘如下(后面慢慢寻找答案):
三种日志处理模式(journal、order、writeback)如何设置什么时候设置?
三种日志处理模式下data和 metadata journal和metadata的落盘顺序?
三种日志处理模式下都是分别如何保证文件系统的完整性?
网友评论