xfs的故障记录

##前言 我使用xfs比较二一点,我是在ceph的rbd上直接格式化的xfs,因此ceph上的数据通常不会丢失,不过个人xfs是在docker内部进行的挂载,使用也是docker容器内使用,这里不得不说docker stop容器的时候仍是至关的暴力,暴力到什么程度呢?xfs大多会在硬盘忽然断电的状况下致使日志文件的写入损坏,故障每每就在这时发生,而docker stop容器和忽然断电能够画上等号。最为悲催的是,我刚开始对xfs一无所知。ceph的rbd也是只知其一;不知其二。而数据是万万不能丢失的,因此中间折腾了好长时间。html

###故障现象 marathon上是没法中止或者没法启动容器的,容器进程实际已经卡死,登陆到后台,kill进程已经没有意义了,压根就不起做用。 message报错以下:linux

Sep 19 10:05:44 [localhost] kernel: XFS: Internal error XFS_WANT_CORRUPTED_GOTO at line 1590 of file /builddir/build/BUILD/kernel-tlinux2-3.10.101/kernel-tlinux2-3.10.101/fs/xfs/xfs_alloc.c.  Caller 0xffffffff8130fadd

Sep 19 10:05:44 [localhost] kernel: CPU: 1 PID: 5826 Comm: mount Tainted: G        W  O 3.10.101-1-tlinux2-0037.tl2 #1
Sep 19 10:05:44 [localhost] kernel: Hardware name: Huawei XH310 V3/BC21DUSA0, BIOS 1.13 09/19/2015
Sep 19 10:05:44 [localhost] kernel: ffff8803f5aa4000 000000006315a611 ffff8803fc2f5b00 ffffffff81b2a080
Sep 19 10:05:44 [localhost] kernel: ffff8803fc2f5b18 ffffffff812f563b ffffffff8130fadd ffff8803fc2f5bc0
Sep 19 10:05:44 [localhost] kernel: ffffffff8130e008 ffff8803fa40c000 ffff8803fe56b000 ffff8803fe508480
Sep 19 10:05:44 [localhost] kernel: Call Trace:
Sep 19 10:05:44 [localhost] kernel: [<ffffffff81b2a080>] dump_stack+0x19/0x1b
Sep 19 10:05:44 [localhost] kernel: [<ffffffff812f563b>] xfs_error_report+0x3b/0x40
Sep 19 10:05:44 [localhost] kernel: [<ffffffff8130fadd>] ? xfs_free_extent+0x12d/0x170
Sep 19 10:05:44 [localhost] kernel: [<ffffffff8130e008>] xfs_free_ag_extent+0x458/0x970
Sep 19 10:05:44 [localhost] kernel: [<ffffffff8130fadd>] xfs_free_extent+0x12d/0x170
Sep 19 10:05:44 [localhost] kernel: [<ffffffff813508c0>] xlog_recover_process_efi+0x1a0/0x1e0
Sep 19 10:05:44 [localhost] kernel: [<ffffffff81367154>] ? xfs_trans_ail_cursor_init+0x24/0x30
Sep 19 10:05:44 [localhost] kernel: [<ffffffff813525b2>] xlog_recover_process_efis.isra.18+0x72/0xd0
Sep 19 10:05:44 [localhost] kernel: [<ffffffff81356471>] xlog_recover_finish+0x21/0xb0
Sep 19 10:05:44 [localhost] kernel: [<ffffffff81360704>] xfs_log_mount_finish+0x54/0x70
Sep 19 10:05:44 [localhost] kernel: [<ffffffff81359924>] xfs_mountfs+0x474/0x740
Sep 19 10:05:44 [localhost] kernel: [<ffffffff81307479>] xfs_fs_fill_super+0x299/0x320
Sep 19 10:05:44 [localhost] kernel: [<ffffffff81173908>] mount_bdev+0x1b8/0x1f0
Sep 19 10:05:44 [localhost] kernel: [<ffffffff813071e0>] ? xfs_parseargs+0xc40/0xc40
Sep 19 10:05:44 [localhost] kernel: [<ffffffff81305595>] xfs_fs_mount+0x15/0x20
Sep 19 10:05:44 [localhost] kernel: [<ffffffff811741e5>] mount_fs+0x15/0xc0
Sep 19 10:05:44 [localhost] kernel: [<ffffffff8118da1f>] vfs_kern_mount+0x5f/0xf0
Sep 19 10:05:44 [localhost] kernel: [<ffffffff8118fe6d>] do_mount+0x21d/0xab0
Sep 19 10:05:44 [localhost] kernel: [<ffffffff8111003e>] ? __get_free_pages+0xe/0x50
Sep 19 10:05:44 [localhost] kernel: [<ffffffff81190796>] SyS_mount+0x96/0xf0
Sep 19 10:05:44 [localhost] kernel: [<ffffffff81c0cce2>] system_call_fastpath+0x16/0x1b
Sep 19 10:05:44 [localhost] kernel: XFS (rbd0): Failed to recover EFIs
Sep 19 10:05:44 [localhost] kernel: XFS (rbd0): log mount finish failed

一开始没想到会是文件系统损坏,由于没有理太清楚ceph的rbd和xfs之间的关系,其实也没有查到会是xfs出了问题。仍是在怀疑ceph的rbd可能什么资源没有释放。 ###怀疑rbd资源未释放 ceph的rbd是有锁的,他要保证数据的一致性,当有一个客户端挂载以后会当即加锁记录到ceph当中。查看锁的方法docker

[root@localhost /data]# rbd lock ls data/test
There is 1 exclusive lock on this image.
Locker        ID       Address                
client.514151 test  192.168.1.3:0/1002880

若是发现列表中有不正常的锁,能够运行下面的命令进行清理:网络

##命令格式
lock remove <image-name> <id> <locker> 
[root@localhost /data]# rbd lock remove data/test  test  client.514151

我也这么干了,可是发现问题依旧,rbd仍是挂载不上,容器一启动就卡死,docker连ps都运行不出来,只得带外重启系统才能释放资源、清理进程。为了缩小问题的范围,我开始尝试手动直接挂载rbd,就在作好本地映射准备挂载的时候,提示文件系统报错,没法挂载。这也就是说docker没有问题,应用也正常,ceph -s以后一切也ok,惟一出问题就是在rbd之上的xfs文件系统。 ###恍惚之间的艰难选择 xfs我是一窍不通,我开始压根没太以为这玩意会每天出问题。网上找了一通以后,开始尝试先恢复数据。 尝试dump rbd的数据:ui

xfs_metadump -o   /dev/rbd0    /data/rbd0.metadump (加-o参数,否则元数据会显示乱码)

还原:this

xfs_mdrestore    rbd0.metadump      rbd0.img

这个时候尝试进行挂载rbd0.img,发现问题依旧,仍是不行,因而开始修复url

xfs_repair -L rbd0.img

而后挂载,又报错,提示dmesg|tail查问题,其实就是uuid重复的问题,这样挂载就行了:rest

mount  -t  xfs  -o  nouuid rbd0.img   /data1/

挂载检查以后发现,文件目录和文件名称正常,数据大小也没有问题,可是每一个文件中都是空的,根本读不出来具体的数据。 思索再三以后才恍然大悟,原来这玩意仅仅是在dump xfs的元数据,每一个文件真实的数据都不包含,你从rbd0.img的大小就能看出来,绝对不是全量的xfs数据。其实xfs全量的dump真正用的命令是xfsdump,一样对应的是xfsrestore,不过挺遗憾的,没有实验这组命令:日志

xfsdump -l 0  -f /dev/rbd0  /data/dump/

具体的使用要看这里 若是你要用xfsdump恢复数据,建议用管道的方式(xfsdump -J -s people/fred - /usr | xfsrestore - /usr2)进行恢复,由于xfsdump须要准备一个额外的同等大小的分区来进行数据还原,而不是仅仅是数据的大小。 其实xfsdump并不适合解决个人问题,百度谷歌一通以后,仍是倾向于直接xfs_repair -L,可是-L说会丢失部分日志数据,这个怕是我背不起的。因此在作这个以前,我想先备份一下现有数据。省的我最后的救命稻草没了,就死翘翘了。 ###数据备份 备份有两个办法:code

  1. 借助ceph rbd的导出功能,将整个rbd块所有导出,保存好导出的数据,就能够对原有的rbd快进行repair操做了,这个确定能成功,并且比较稳妥,问题就是慢,速度不怎么快,毕竟是数据大,网络传输须要时间,另外就是你的rbd块设备总共多大,你导出来的文件就有多大,你得当心这个。
rbd  export  test  test.img
  1. 借助xfs_copy将两个块设备进行数据copy。
xfs_copy  /dev/rbd0  /dev/rbd1

这个速度要比第一个能高一半,可是目标块设备的大小要大于源块设备,并且文件系统也必须是xfs,不过遗憾的是,这个方式无法用,由于到最后90%的时候它是不管如何也到不了100%的,缘由很简单源块设备的文件系统是坏的,xfs_copy只能在两个正常的xfs文件系统中复制数据。因此费了咱们好多时间。 ###临终 最终仍是直接xfs_repair -L 直接在ceph的源故障块上进行操做修复的。这里附上疑似华为的解决文档做为参考,之后再遇到此故障,放心大胆的搞,传送门 最后,生死由命,富贵在天,你在dump的时候多拜拜春哥:

相关文章
相关标签/搜索