##前言 我使用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
rbd export test test.img
xfs_copy /dev/rbd0 /dev/rbd1
這個速度要比第一個能高一半,可是目標塊設備的大小要大於源塊設備,並且文件系統也必須是xfs,不過遺憾的是,這個方式無法用,由於到最後90%的時候它是不管如何也到不了100%的,緣由很簡單源塊設備的文件系統是壞的,xfs_copy只能在兩個正常的xfs文件系統中複製數據。因此費了咱們好多時間。 ###臨終 最終仍是直接xfs_repair -L 直接在ceph的源故障塊上進行操做修復的。這裏附上疑似華爲的解決文檔做爲參考,之後再遇到此故障,放心大膽的搞,傳送門 最後,生死由命,富貴在天,你在dump的時候多拜拜春哥: