手工修复 xfs 文件系统

这几天,机器都出故障。网通ADSL虚拟拔号上网,在windows系统中就会出现频繁的 ip冲突 提示。在SuSE系列的Linux系统中就是频繁死机,只能按reset重启机器。详细情况请看网通ADSL单机拔号,windows下频繁ip冲突。suse系列2小时内必定当机(求非硬件解决方案) 。
reset后的结果就是,再次启动Linux系统时,会首先挂载根目录,如果根目录的文件系统受到破坏会首先修复根文件系统。然后再检查其它的挂载设 备。根文件系统默认开机是会自检的,如果根文件系统有损坏,在启动时就能够最先修复。如果能够正常修复,就通顺利的挂载根目录。
但是,往往系统被挂载的不仅仅有根文件系统,还有一些目录可能是一个单独的磁盘分区。这些磁盘分区,这些文件系统,在 /etc/fstab 文件中并不总是开机就自检的。/etc/fstab文件中最后面的两个阿拉伯数字,最后面的一位数字为 1 或者是 2 都表示开机自检的。根分区是第一个被自检的,所以标识为 1 。
例如:

/dev/hda10           /                    reiserfs   defaults              1 1
proc                 /proc                proc       defaults              0 0
sysfs                /sys                 sysfs      noauto                0 0
debugfs              /sys/kernel/debug    debugfs    noauto                0 0
usbfs                /proc/bus/usb        usbfs      noauto                0 0
devpts               /dev/pts             devpts     mode=0620,gid=5       0 0
/dev/hda3            /media/hda3         reiserfs    defaults              0 0
/dev/hda13           /media/hda13         xfs        defaults              1 2

但是,我就发现了,在非正常关机之后我的 xfs 的磁盘分区无法挂载。
如果使用的是SLES-10-GM-i386的系统,如果/etc/fstab中有未被挂载的,系统启动后是不正常的,提示符是不一样的。
如果使用的是SLES-10-GM-x86_64的系统,只要根文件系统被挂载,提示符是正常的。

opensuse-10.2-GM-x86_64的系统在处理文件系统故障的时候要优于 SLES-10 。大多数时候,都能够在启动的时候就自动修复文件系统,包括 xfs 。但也有少数时候不能顺利的在启动时修复。

如果系统在启动时不能够修复受损的文件系统,那就只好手工的来修复了。
通常都是使用fsck命令的修复文件系统的。例如 fsck.ext3 。
但这里的 xfs 文件系统不可以用fsck.xfs的命令来修复。如果运行这个命令会提示使用xfs_check和xfs_repair 。如:

sles10:~ # fsck.xfs
If you wish to check the consistency of an XFS filesystem or
repair a damaged filesystem, see xfs_check(8) and xfs_repair(8).

如果有兴趣可以看一下这两个工具的man帮助。我的英文太差,看起来比较吃力。在网上搜索了下,看到有关于修复 xfs 的文章。我就照着试了下:
先用xfs_check检查xfs文件系统。
sles10:~ # xfs_check /dev/hda13
出来一段英文提示
提示中的大概意思是说使用 xfs_repair 加 -L 的参数清除xfs文件系统中的日志。
这时就可以根据提示进行清除xfs文件中的这些的日志。之所以要删除,是因为在文件系统非正常卸载的瞬间,数据还在缓存中没有被及时的写入磁盘。
sles10:~ # xfs_repair -L /dev/hda13
这时,在可以看到删除日志的过程。
如这样的字样在向上翻滚:

data fork in ino 14780353 claims free block 7524000
data fork in ino 14780353 claims free block 7524001
data fork in ino 14780353 claims free block 7524002
data fork in ino 14780353 claims free block 7524003
data fork in ino 14780353 claims free block 7524004
data fork in ino 14780353 claims free block 7524005
data fork in ino 14780353 claims free block 7524006
data fork in ino 14780353 claims free block 7524007
data fork in ino 14780353 claims free block 7524008
data fork in ino 14780353 claims free block 7524009
data fork in ino 14780353 claims free block 7524010
data fork in ino 14780353 claims free block 7524011
data fork in ino 14780353 claims free block 7524012
data fork in ino 14780353 claims free block 7524013
data fork in ino 14780353 claims free block 7524014
data fork in ino 14780353 claims free block 7524015
data fork in ino 14780353 claims free block 7524016
data fork in ino 14780353 claims free block 7524017
data fork in ino 14780353 claims free block 7524018
data fork in ino 14780353 claims free block 7524019
data fork in ino 14780353 claims free block 7524020
data fork in ino 14780353 claims free block 7524021
data fork in ino 14780353 claims free block 7524022
data fork in ino 14780353 claims free block 7524023
data fork in ino 14780353 claims free block 7524024
data fork in ino 14780353 claims free block 7524025
data fork in ino 14780353 claims free block 7524026
data fork in ino 14780353 claims free block 7524027
data fork in ino 14780353 claims free block 7524028
data fork in ino 14780353 claims free block 7524029
data fork in ino 14780353 claims free block 7524030
data fork in ino 14780353 claims free block 7524031
data fork in ino 14780353 claims free block 7524032
data fork in ino 14780353 claims free block 7524033
data fork in ino 14780353 claims free block 7524034
data fork in ino 14780353 claims free block 7524035
data fork in ino 14780353 claims free block 7524036
data fork in ino 14780353 claims free block 7524037
data fork in ino 14780353 claims free block 7524038
data fork in ino 14780353 claims free block 7524039
data fork in ino 14780353 claims free block 7524040
data fork in ino 14780353 claims free block 7524041
data fork in ino 14780353 claims free block 7524042
data fork in ino 14780353 claims free block 7524043
data fork in ino 14780353 claims free block 7524044
data fork in ino 14780353 claims free block 7524045
data fork in ino 14780353 claims free block 7524046
data fork in ino 14780353 claims free block 7524047
data fork in ino 14780353 claims free block 7524048
data fork in ino 14780353 claims free block 7524049
data fork in ino 14780353 claims free block 7524050
data fork in ino 14780353 claims free block 7524051
data fork in ino 14780353 claims free block 7524052
data fork in ino 14780353 claims free block 7524053
data fork in ino 14780353 claims free block 7524054
data fork in ino 14780353 claims free block 7524055
data fork in ino 14780353 claims free block 7524056
data fork in ino 14780353 claims free block 7524057
data fork in ino 14780353 claims free block 7524058
data fork in ino 14780353 claims free block 7524059
data fork in ino 14780353 claims free block 7524060
data fork in ino 14780353 claims free block 7524061
data fork in ino 14780353 claims free block 7524062
data fork in ino 14780353 claims free block 7524063
data fork in ino 14780353 claims free block 7524064
data fork in ino 14780353 claims free block 7524065
– agno = 1
– agno = 2
– agno = 3
correcting key in bmbt root (was 274896, now 274688) in inode 63496376 data fork
correcting nblocks for inode 63496376, was 38232 – counted 38120
correcting nextents for inode 63496376, was 1608 – counted 1593
correcting key in bmbt root (was 288008, now 288100) in inode 63496377 data fork
correcting key in bmbt root (was 535628, now 535620) in inode 63496377 data fork
data fork in regular inode 63496377 claims used block 7512807
bad data fork in inode 63496377
cleared inode 63496377
– agno = 4
– agno = 5
– agno = 6
– agno = 7
– agno = 8
– agno = 9
– agno = 10
– agno = 11
– agno = 12
– agno = 13
– agno = 14
– agno = 15
– process newly discovered inodes…
Phase 4 – check for duplicate blocks…
– setting up duplicate extent list…
– clear lost+found (if it exists) …
– check for inodes claiming duplicate blocks…
– agno = 0
entry “debian-31r4-amd64-binary-2.iso” at block 0 offset 944 in directory inode 128 references free inode 63496377
clearing inode number in entry at offset 944…
data fork in ino 14780353 claims dup extent, off – 291984, start – 7512803, cnt 11556
bad data fork in inode 14780353
cleared inode 14780353
– agno = 1
– agno = 2
– agno = 3
– agno = 4
– agno = 5
– agno = 6
– agno = 7
– agno = 8
– agno = 9
– agno = 10
– agno = 11
– agno = 12
– agno = 13
– agno = 14
– agno = 15
Phase 5 – rebuild AG headers and trees…
– reset superblock…
Phase 6 – check inode connectivity…
– resetting contents of realtime bitmap and summary inodes
– ensuring existence of lost+found directory
– traversing filesystem starting at / …
rebuilding directory inode 128
– traversal finished …
– traversing all unattached subtrees …
– traversals finished …
– moving disconnected inodes to lost+found …
Phase 7 – verify and correct link counts…
done

好了,现在再试试挂载这个 xfs 的分区就可以了。
sles10:~ # mount /dev/hda13
由于 /etc/fstab 中有记录,所以命令就不必打全了。打一半,就会自动从 /etc/fstab 或者 /etc/mtab 中找到记录,并挂载。

看过CU论坛上的楚老师做的视频教程--楚广明24小时学通Linux视频教程。里面讲到过日志文件系统的原理。大概意思是这样:在日志文件系统中, 向文件系统中写入数据时,先会将数据写到缓存中,等到缓存满的时候才从缓存中把数据写入到要写入的地方。这一过程相当于数据库中的一个事务。如果数据还在 缓存中,还没有写入到要写入的位置时,就出现故障,就相当于一次失败的事务。

关于目志文件系统的解释:
————————————————————————————–
什么是日志文件系统
• 日志文件系统的设计思想是跟踪文件系统的变化而不是文件系统的内
容。它用独立的日志文件跟踪磁盘内容的变化,就像关系型数据库
(RDBMS),因而比传统的文件系统安全。日志文件系统可以用事务处理
的方式,提交或撤消文件系统的变化。当系统非正常关闭,处于写入磁
盘过程中的文件系统被非正常卸载,文件系统就会处于不一致的状态。
为了尽量减少文件系统的不一致性,缩短操作系统的启动时间,文件系
统需追踪引起系统改变的记录,这些记录存放在与文件系统相分离的地
方,通常称为“日志”。一旦这些日志记录被安全地写入,日志文件系统就
可以将它们应用到文件系统中,清除引起系统发生改变的记录,并将它
们组成一个引起文件系统改变的集。
日志文件的主要作用就是可以最大程度地保证文件系统的一致性。通常
文件系统存放日志记录,当重新引导计算机启动时,安装程序为保证文
件系统的一致性会检测日志记录,并将它安全地、完整地应用到文件系
统中。在大多数情况下,一般操作系统并不检测文件系统的一致性,使
用日志文件系统的计算机则会在系统引导后,立即使用日志检测,降低
数据丢失的可能性。
————————————————————————————
<–> <–><–><–><–><–><–><–><–><–><–><–><–><–><–><–><–><–><–><–><–><–><–><–><–><–><–>
现在的文件系统一般都是“缓冲型”文件系统。当数据进行读写的时候,并不是每对数据操作一次,就会对硬盘操作一次。而是先缓存到一个地方,比如内存或者是 硬盘上的缓存。当缓存区满时,会一次性写入到硬盘。如果当文件向硬盘进行写入的这一时间,系统被重启或者断电,这时候缓存区中的数据就会被丢掉。这样就会 造成文件系统的不一致性。
日志性文件系统是借鉴了关系型数据库(RDBMS)的技术来实现的。通过日志文件,相当于数据库中的事务。文件系统的读取是一个部分,只要数据没有写到硬 盘上,日志上就会有个“x” 。这个文件就称之为“脏文件”。如果当缓存区满的时候,文件被顺利的写到硬盘上之后,会在日志上完成这项功能,表示这个数据已经“干净”了,已经完整的写 到硬盘上了。这个日志和文件系统是两个独立的系统,日志文件的最大特点是可以保证文件系统的一致性。

此条目发表在未分类分类目录。将固定链接加入收藏夹。