找回密码
 注册
查看: 937|回复: 7

ceph 分布式存储mds 修复

[复制链接]

0

主题

0

回帖

9

积分

管理员

积分
9
QQ
发表于 2022-8-3 11:02:40 | 显示全部楼层 |阅读模式

解决:两种方法:

  • 方法一:

      #ceph mds repaired AI_Spacefs:0
  • #ceph mds repaired AI_Spacefs:1, S' t, T5 |6 ^  [8 I  w' w) x6 y

    • % H" I, q& T' W' r9 B* C

    此方法一般情况下是好使,当有osd stuck的状态时也会失效。这个时候要重启osd,若未发现stuck就要手动触发数据迁移把stuck的osd暴露出来。然后再执行上面的操作。
    1 V9 W( D* D3 c6 B& t! t) p经测试,有两次都是通过上述方法解决问题的。

  • 方法二:  [! Z- g$ m6 C. }
    这次问题要严重的多,所有的mds都没有active的状态,造成元数据无法恢复,方法一失效,所以此时需要放弃原来的cephfs,重建构建基于原来data池生成新的cephfs.

    / M7 a5 E2 g2 r7 X$ R, p9 T0 Y- P

元数据故障恢复

设置允许多文件系统

ceph fs flag set enable_multiple true --yes-i-really-mean-it
  • , ~# I8 W7 r" g9 ~2 f

创建一个新的元数据池,这里是为了不去动原来的metadata的数据,以免损坏原来的元数据

ceph osd pool create recovery 8
  • : s# y) O7 r, }1 ^) q, q

将老的存储池data和新的元数据池recovery关联起来并且创建一个新的recovery-fs

ceph fs new recovery-fs recovery AI_Spacefs_data --allow-dangerous-metadata-overlay
  • - L4 b# y8 D( {# X

做下新的文件系统的初始化相关工作

#cephfs-data-scan init --force-init --filesystem recovery-fs --alternate-pool recovery
3 f' H% Y" \3 f* Q9 o; k# q- J% q2020-03-18T16:22:50.508+0800 7f4a11a1d700 -1 NetHandler create_socket couldn't create socket (97) Address family not supported by protocol

  • ! r  _2 j; ]2 W7 ]* A& `$ H1 Q' O

出现上述的错误可以忽略进行下一步。

reset下新的fs

#ceph fs reset recovery-fs --yes-i-really-mean-it若失败,要把所有mds fail掉或者stop掉,再快速执行上面命令。#cephfs-table-tool recovery-fs:all reset session#cephfs-table-tool recovery-fs:all reset snap#cephfs-table-tool recovery-fs:all reset inode出现Address family not supported by protocol的错误忽略掉

  • 2 G9 f! I, b8 `, q! T( F5 S6 m

做相关的恢复

做下一步之前确保新建的recovery-fs没有active的mds,有则stop掉,不然该mds容易crashed。#cephfs-data-scan scan_extents --force-pool --alternate-pool recovery --filesystem AI_Spacefs AI_Spacefs_data) S, r6 w3 D; V5 k3 W

8 P' X9 ~( X7 N, K$ u5 @#cephfs-data-scan scan_inodes --alternate-pool recovery --filesystem AI_Spacefs -force-corrupt --force-init AI_Spacefs_data* G* i) E# r* r6 K
2 W1 A/ w1 v( j4 r
#cephfs-data-scan scan_inodes --alternate-pool recovery --filesystem AI_Spacefs --force-corrupt --force-init AI_Spacefs_data, H0 F8 ~  F4 j$ S, F5 Y' h; p
' m9 |6 \$ ]2 B/ X
#cephfs-data-scan scan_links --filesystem recovery-fs, v) |; f# p6 M' J# E

3 L7 k2 @( z9 I1 L+ X出现Address family not supported by protocol的错误忽略掉
0 K7 q# j" X" v3 n; |; R( O  C' w. Q- g
# systemctl start ceph-mds@node82等待mds active 以后再继续下面操作
* }' j$ K$ c3 F. F1 l' D3 c) D& X# ceph daemon mds.node82 scrub_path / recursive repair( Q7 w9 q" J4 i* ~* m" T! H
/ @0 {) t# _4 \
事实上上面这一步并没有操作数据就已经恢复了。: v  o% s" h  Y6 N
: U  n! ~1 W) w' l

设置成默认的fs


- K1 B+ t; H* J4 G5 v( \) D- R' c

# ceph fs set-default recovery-fs

  • ( z6 {0 ]& U( Y# ?" U% \/ c

挂载检查数据

[root@node82 lyf3]# lsDATASET  lost+found  SYSTEM  USER; K4 V6 O  e; V# j: @

, Y0 R9 n( V& a8 _[root@node82 lyf3]# ll" M/ U0 w* u4 s$ D4 E* k

: S8 {, U4 g7 c2 ^3 A lost+found/total 1-r-x------ 1 root root 237 Mar 11 13:21 1000172efb8
  • % S, l) ^) x* Z9 q; H& I& l6 Y

可以看到在lost+found里面就有数据了这个生成的文件名称就是实际文件存储的数据的prifix,也就是通过原始inode进行的运算得到的。

如果提前备份好了原始的元数据信息

# ceph daemon mds.node82 dump cache > /tmp/mdscache
  • 6 `9 [; @0 u8 {: s

那么可以比较轻松的找到丢失的文件

原作者总结

通过文件的inode可以把文件跟后台的对象结合起来,在以前我的恢复的思路是,把后台的对象全部抓出来,然后自己手动去对对象进行拼接,实际是数据存在的情况下,反向把文件重新link到一个路径,这个是官方提供的的恢复方法,mds最大的担心就是mds自身的元数据的损坏可能引起整个文件系统的崩溃,而现在,基本上只要data的数据还在的话,就不用担心数据丢掉,即使文件路径信息没有了,但是文件还在

通过备份mds cache可以把文件名称,路径,大小和inode关联起来,而恢复的数据是对象前缀,也就是备份好了mds cache 就可以把整个文件信息串联起来了

虽然cephfs的故障不是常发生,但是万一呢

后续准备带来一篇关于cephfs从挂载点误删除数据后的数据恢复的方案,这个目前已经进行了少量文件的恢复试验了,等后续进行大量文件删除的恢复后,再进行分享


+ C# m5 A# [! T
+ v; o* U! p, t+ K# w( y4 v' Q4 K
, e3 [& _& ]2 E
# \1 {4 ]& P! n

0

主题

0

回帖

9

积分

管理员

积分
9
QQ
 楼主| 发表于 2022-8-3 11:47:03 | 显示全部楼层
元数据故障恢复- D# ~& m. m/ U( A8 A
设置允许多文件系统0 a& w4 p' d8 x7 h
5 f6 L" d- }* f. ~
ceph fs flag set enable_multiple true --yes-i-really-mean-it
! ^2 N- Q3 {0 e6 v6 z! w3 |! e% F创建一个新的元数据池,这里是为了不去动原来的metadata的数据,以免损坏原来的元数据
5 `+ j6 F6 E+ X6 E  S9 e3 B: F7 A* H0 ]% U3 V" {
ceph osd pool create recovery 8. h; R: Q; b. u/ ~5 b8 W! [
将老的存储池data和新的元数据池recovery关联起来并且创建一个新的recovery-fs
4 i2 P; U/ p! Q3 x; Z  ?8 l  f* S9 E( N4 O
[root@lab102 ~]# ceph fs new recovery-fs recovery data --allow-dangerous-metadata-overlay! ?; ]4 b% ?9 B% A& d, X; _
new fs with metadata pool 3 and data pool 2
1 ?9 r3 ~) U' \做下新的文件系统的初始化相关工作
& Z: F0 }& Y3 j. U9 o% I( z. a( `3 y5 Z. H& X& O( `5 i
[root@lab102 ~]#cephfs-data-scan init --force-init --filesystem recovery-fs --alternate-pool recovery
" A1 p. j6 L/ h5 Dreset下新的fs# a* J9 K4 _" w! S$ g
# S, a+ y% `6 p! o3 C3 p6 \+ Z$ D
[root@lab102 ~]#ceph fs reset recovery-fs --yes-i-really-mean-it) u2 m6 M. H; F
[root@lab102 ~]#cephfs-table-tool recovery-fs:all reset session7 ?0 S- K; i7 u  G7 B
[root@lab102 ~]#cephfs-table-tool recovery-fs:all reset snap
6 r" c: J/ J* L( [. f8 S[root@lab102 ~]#cephfs-table-tool recovery-fs:all reset inode/ F  O6 Y" j# W' x& x9 S% A1 F
做相关的恢复& ?: Y2 J/ L! p
1 @5 T- R+ a) R, R
[root@lab102 ~]# cephfs-data-scan scan_extents --force-pool --alternate-pool recovery --filesystem ceph  data
# t) H& ?: D. h4 ]  r[root@lab102 ~]# cephfs-data-scan scan_inodes --alternate-pool recovery --filesystem ceph --force-corrupt --force-init data
6 _/ y' _; q! }  a[root@lab102 ~]# cephfs-data-scan scan_links --filesystem recovery-fs. U) C! K. W$ r
[root@lab102 ~]# systemctl start ceph-mds@lab102
9 i( c+ s; E- T# M等待mds active 以后再继续下面操作
9 c, d  h: q7 V% H9 p; j  s( E  _$ I[root@lab102 ~]# ceph daemon mds.lab102 scrub_path / recursive repair
5 c: d, V/ ?- \( ~& S) v% o设置成默认的fs
) H3 {' [  K, ^/ e9 {
- C" h, Z, a$ d  n# {6 s[root@lab102 ~]# ceph fs set-default recovery-fs3 H; c' T9 W& v
挂载检查数据: s: N/ z# I7 ^0 t  P% }

' D8 N. E) s( Y9 S! @' k[root@lab102 ~]#  mount -t ceph 192.168.19.102:/ /mnt
; X& X5 L7 a6 f[root@lab102 ~]# ll /mnt6 @, E( z- ~0 d
total 0" P: v2 X5 [, ^) r2 K5 i
drwxr-xr-x 1 root root 1 Jan  1  1970 lost+found
2 g# D2 I9 m  a2 c- r; S% _% R. E[root@lab102 ~]# ll /mnt/lost+found/
* [% O. I- ]; ]9 N9 w% s/ E1 f" @total 226986: G  l0 `5 |6 Y, F
-r-x------ 1 root root   569306 May 25 16:16 10000000001
) I8 @% O. k5 l% r7 }% w: m-r-x------ 1 root root 16240627 May 25 16:16 10000000002& y! ~. P2 q7 C
-r-x------ 1 root root  1356367 May 25 16:16 10000000003, S/ S) v& R5 b
-r-x------ 1 root root   137729 May 25 16:16 10000000004
  C. Z1 _- \5 B( _* l! V-r-x------ 1 root root   155163 May 25 16:16 10000000005
# Y" P7 O. R. N-r-x------ 1 root root   118909 May 25 16:16 10000000006
5 P( u9 n- u+ a' }-r-x------ 1 root root  1587656 May 25 16:16 10000000007
* t3 W- ^! |* ?% W! W-r-x------ 1 root root   252705 May 25 16:16 10000000008( R* x' @' k# b3 a4 T! L
-r-x------ 1 root root  1825192 May 25 16:16 100000000093 d/ f, T  T5 s7 G4 Q
-r-x------ 1 root root   156990 May 25 16:16 1000000000a4 |/ t: m  h+ n' b
-r-x------ 1 root root  3493435 May 25 16:16 1000000000b( J$ e- m" Y' H
-r-x------ 1 root root   342390 May 25 16:16 1000000000c
' ?- ]3 i" J* J% O) A- M) B  {-r-x------ 1 root root  1172247 May 25 16:16 1000000000d
  C6 P' ?2 t6 ~" {2 J+ Q-r-x------ 1 root root  2516169 May 25 16:16 1000000000e
7 A) e8 a3 r' _) k& U7 t-r-x------ 1 root root  3218770 May 25 16:16 1000000000f8 A6 S7 e) e8 h3 n
-r-x------ 1 root root   592729 May 25 16:16 10000000010$ _# ?5 f" I; Y. a
可以看到在lost+found里面就有数据了
- z5 G2 x2 ?' a/ H2 r4 f6 s: T
) {: J: a9 w! Y/ s% i[root@lab102 ~]# file /mnt/lost+found/10000000010
# Q; q0 C: b3 h6 Y% |. r/mnt/lost+found/10000000010: Microsoft PowerPoint 2007+
9 n! x- C' I7 {3 ]2 G[root@lab102 ~]# file /mnt/lost+found/10000000011
  ?- Z$ h) b+ Z( Z% {  o3 d7 I/mnt/lost+found/10000000011: Microsoft Word 2007+. d  I5 I3 a& o# X( r; d: b
[root@lab102 ~]# file /mnt/lost+found/10000000012$ D  F  e( O/ G& p/ Y( J( x
/mnt/lost+found/10000000012: Microsoft Word 2007+
' i# B: W1 ?: j% Q/ O7 [. y& B2 ][root@lab102 ~]# file /mnt/lost+found/10000000013" ]* y( o& n: I8 V- |3 A  ?8 X
/mnt/lost+found/10000000013: Microsoft PowerPoint 2007+
+ f/ d3 Q+ ?5 N, D; q! A这个生成的文件名称就是实际文件存储的数据的prifix,也就是通过原始inode进行的运算得到的3 L; P! _) z( P1 X& S. q" u5 A  @9 i) |

& n2 x; k. [0 [+ ?* i如果提前备份好了原始的元数据信息+ i, i! z/ A# B- ]' @. A, h$ ]$ E

5 W6 k( @/ ]* B* W: q; \: Q" |9 f[root@lab102 ~]# ceph daemon mds.lab102 dump cache > /tmp/mdscache
- z1 {0 x2 p# @那么可以比较轻松的找到丢失的文件

0

主题

0

回帖

9

积分

管理员

积分
9
QQ
 楼主| 发表于 2022-8-3 11:48:13 | 显示全部楼层
解决:两种方法:& L1 O) O, h% C( E4 x
7 _9 L$ X( I/ Y7 S' ~1 L: m+ Y
方法一:
. R% l+ S/ ?% j, C) {1 F+ x/ M& n
/ e7 d, k) R! Y' Q: J* Y  #ceph mds repaired AI_Spacefs:0
& l4 ~, {! [6 A  #ceph mds repaired AI_Spacefs:1  L( @1 E, k. [5 ?& e0 m( v% f( H1 s
此方法一般情况下是好使,当有osd stuck的状态时也会失效。这个时候要重启osd,若未发现stuck就要手动触发数据迁移把stuck的osd暴露出来。然后再执行上面的操作。% Y% y: \& E/ S7 r3 K; B
经测试,有两次都是通过上述方法解决问题的。
/ f, b$ V- U; x; P* N* ~6 v- ^) }6 M# g. B) a  a  Z' F4 ?+ M
方法二:( i" \; u& W% P1 ]
这次问题要严重的多,所有的mds都没有active的状态,造成元数据无法恢复,方法一失效,所以此时需要放弃原来的cephfs,重建构建基于原来data池生成新的cephfs.* }& s7 A% n4 @8 q6 ~& h
' J: E4 C( D6 U$ y6 E- ?" Q8 ?
元数据故障恢复
7 e6 ~# }1 T8 h& h, o6 v% {( Y8 l' t
设置允许多文件系统! y/ J: a0 A' N+ B4 X$ P0 |

& _! [5 k. n% G6 Wceph fs flag set enable_multiple true --yes-i-really-mean-it
+ ]" m8 b* E# f创建一个新的元数据池,这里是为了不去动原来的metadata的数据,以免损坏原来的元数据
! Y% @( b6 j/ D, y8 Q0 N8 b- G+ B/ O/ I$ P, s% k" T" `! P6 n( }! T+ D" t: I
ceph osd pool create recovery 8& u& V( `8 P, M8 h
将老的存储池data和新的元数据池recovery关联起来并且创建一个新的recovery-fs" V8 X0 I9 h% a1 n# M4 c( C
2 q- y- \1 |3 O* H' N
ceph fs new recovery-fs recovery AI_Spacefs_data --allow-dangerous-metadata-overlay
) x% B) ^# e5 n7 K" v# U8 u做下新的文件系统的初始化相关工作1 r: r( n# I3 `8 a, l

7 y  J( Q& ~$ k+ N& d! i+ O#cephfs-data-scan init --force-init --filesystem recovery-fs --alternate-pool recovery
5 b' V2 Z6 f9 {, ]+ ]; c% t" p* \2020-03-18T16:22:50.508+0800 7f4a11a1d700 -1 NetHandler create_socket couldn't create socket (97) Address family not supported by protocol
; @+ n. u- M. g2 q出现上述的错误可以忽略进行下一步。
* w8 y  T$ B1 L& [& J1 q
& @2 T1 b( H$ |0 ~: K9 nreset下新的fs9 F8 s0 W' [2 Y. X; v

8 N7 ]9 q4 C! n7 ?6 M2 d#ceph fs reset recovery-fs --yes-i-really-mean-it0 V- u4 L& H2 G" ^8 J3 D
若失败,要把所有mds fail掉或者stop掉,再快速执行上面命令。+ {: H& ~: h, G8 g4 R
#cephfs-table-tool recovery-fs:all reset session
+ m8 F* N4 F2 I4 x& R$ c5 y* o#cephfs-table-tool recovery-fs:all reset snap
1 K0 I. N& f" S7 {#cephfs-table-tool recovery-fs:all reset inode
+ Q0 `$ b4 l) |1 Q出现Address family not supported by protocol的错误忽略掉
, \8 e6 e- ^7 L' G3 `  a) u做相关的恢复& N" c$ @. E5 G. n, m, U1 H, i$ A

! @5 p. [( p* A2 n做下一步之前确保新建的recovery-fs没有active的mds,有则stop掉,不然该mds容易crashed。$ N2 \4 d! t9 R+ ^, X, m
#cephfs-data-scan scan_extents --force-pool --alternate-pool recovery --filesystem AI_Spacefs AI_Spacefs_data
$ @5 m; G) A$ G#cephfs-data-scan scan_inodes --alternate-pool recovery --filesystem AI_Spacefs -force-corrupt --force-init AI_Spacefs_data
! L3 I$ {; B! B6 _- t5 r#cephfs-data-scan scan_inodes --alternate-pool recovery --filesystem AI_Spacefs --force-corrupt --force-init AI_Spacefs_data8 ~. X' h" L1 C1 q- [/ Y
#cephfs-data-scan scan_links --filesystem recovery-fs
% ]5 O/ B( f6 E& L6 B4 i出现Address family not supported by protocol的错误忽略掉% v" k+ z$ H; ]" c( ?" i

5 W$ V2 L$ J0 F; U$ L4 K8 x1 d# l* n# systemctl start ceph-mds@node82) q3 n. x' Y$ U- z, C8 t
等待mds active 以后再继续下面操作
6 [9 ~) ]+ V( `: E3 b7 K# ceph daemon mds.node82 scrub_path / recursive repair
" R+ y8 m: B- ^5 I, l" d/ o事实上上面这一步并没有操作数据就已经恢复了。2 ]' O  X4 E& ?& c7 l1 n* j3 a) F
设置成默认的fs9 E0 V5 ]( U- P0 [" Y

4 ~" Y3 |, Q( E) k+ p8 g" V# ceph fs set-default recovery-fs" M9 I' H2 A& @1 b
挂载检查数据& F% E, U2 L* J& s2 ^5 e

! a1 n# s9 f, T+ `8 |* T5 g9 T[root@node82 lyf3]# ls0 B  m+ E. u* Y" _
DATASET  lost+found  SYSTEM  USER3 v7 {& o( N7 [" C  p. ^  t
[root@node82 lyf3]# ll lost+found/' f: ^: v' E2 x3 ?" ~3 Z# j
total 1# C8 Q, I6 H: [/ v5 \
-r-x------ 1 root root 237 Mar 11 13:21 1000172efb8
4 ~4 J/ ?6 W0 G, F可以看到在lost+found里面就有数据了这个生成的文件名称就是实际文件存储的数据的prifix,也就是通过原始inode进行的运算得到的。, A* _* G' j  U( h

  D  o6 @; j0 H如果提前备份好了原始的元数据信息
( G/ X  h, r7 `' z/ Z# t: N1 Q9 I" w8 X. `7 S: K! I
# ceph daemon mds.node82 dump cache > /tmp/mdscache
7 w: g- V0 @5 @+ ?) c9 |那么可以比较轻松的找到丢失的文件

0

主题

0

回帖

9

积分

管理员

积分
9
QQ
 楼主| 发表于 2022-8-3 11:49:46 | 显示全部楼层
针对原因一:
8 Q( T' ]+ y4 S( e' r0 [+ Y; }) z& n: f
此次情况比较特殊,ceph health detail命令竟然看不到stuck的osd,解决如下:9 ^/ [! P; J3 K4 W  o- o
把 使用率比较高的osd降权重,手动触发osd的数据迁移。5 [" c- c/ B. d# |  d& a
重新ceph health detail命令,此时会发现stuck的osd,重启相应的osd,mds状态恢复。8 p. _  q( U3 ]0 G. C6 j( S/ m
针对原因二(收效甚微):
' |6 c. P/ _# ^8 k$ g3 }
" V1 A5 {. d$ x* O( u$ _3 r调小mds mds_cache_memory_limit到40G 以下, r7 c9 x/ i1 |# O1 `1 A/ A& i
# ceph tell mds.\* injectargs '--mds_cache_memory_limit=40000000000  L0 Q  Q) Q* C
在/etc/ceph/ceph.conf修改,传到所有ceph节点
; ^- d9 g: I6 G4 E5 b2 c, n8 _针对原因三(主要原因):7 n$ v$ R8 Z7 i( I+ I! {/ S

3 Q! X5 J" H0 P- |方法一 mds多活热备调低敏感度,有两个操作:- b" K* j" J9 ~6 H; g' ?/ n6 F

- h( ^$ T) N  w调高mds_beacon_grace=300,调高超时时间。0 P5 |1 }" @9 \. \

3 {5 l- R" r/ a6 v7 W$ B. A  写到/etc/ceph/ceph.conf里,传到所有mds节点,然后重启mds  y1 C) W% e2 ?6 [' J, r
1  D& B/ o8 x) @: H2 `+ [$ }) C
mds采用热备模式,替换原来冷备模式,加快mds加入速度。1 d7 j. U1 e2 f4 `! o, P9 k

) `5 {: @2 {1 ]1 K2 C$ B; ?# ], t  ceph fs set <fs name> allow_standby_replay true
' e0 c8 C9 G- ~( Z. M% I* l1
; k, N% E7 ~1 ~方法二 mds多活热备静态目录方法,即给目录划分不同的mds2 S/ R# {% p# |/ I% t( g" A

7 m# K4 b% d0 a5 B* ^/ q- A命令:
$ @- n9 [. w& Vsetfattr -n ceph.dir.pin -v 2 path/to/dir
) F, n3 J0 Q5 \0 J' Wmkdir -p a/b7 F. w% v8 P3 X( [" q. ?
# “a” and “a/b” both start without an export pin set
  z( s. Q- L5 m5 }' y. R- m9 [setfattr -n ceph.dir.pin -v 1 a/0 }) A& R& {/ r. `( Y
# a and b are now pinned to rank 1
6 W* X4 ]& M% }setfattr -n ceph.dir.pin -v 0 a/b" K7 x/ T- F3 s* B6 Y
# a/b is now pinned to rank 0 and a/ and the rest of its children are still pinned to rank 1
4 R  C& K9 j* x

0

主题

0

回帖

9

积分

管理员

积分
9
QQ
 楼主| 发表于 2022-8-3 11:51:03 | 显示全部楼层
1.创建 cephfs) V5 {; G9 u4 A* S& g" F2 A7 b
一个cephfs至少要求两个librados存储池,一个为data,一个为metadata。
/ `# l, n  j% w7 _- `+ ]8 ^( n
step 1.创建cephfs存储池fs_metadata,fs_data. b9 y2 R* s  ~) Y& K5 q
3 ^7 ^0 `+ j* C; w7 [# |& X
# 元数据库存储池' j  e0 B  Z6 l) K& x
ceph osd pool create cephfs_metadata 8 89 J$ }6 ]8 u: m: F6 K: ^
# 数据1 S# @4 L9 F! c. s+ L& N5 m
ceph osd pool create cephfs_data 8 86 ~+ h# A# I; f/ E# E0 A
step 2.使用fs new命令enable 文件系统
2 Y0 Z" X6 C, K) H. K" m! E9 Y3 b# E& X( G
ceph fs new cephfs cephfs_metadata cephfs_data
) ?! A- e2 D2 h; m使用mds来观察4 {' B( ~# R' {

! f) D: y& |  \, r5 D; P  J[root@ceph-stroage01 ~]# ceph fs ls
" }4 l- M, o6 ~$ V2 B! J( d' Oname: cephfs, metadata pool: fs_metadata, data pools: [fs_data ]' M- U- e3 Z9 _# D& B
[root@ceph-stroage01 ~]#. n% Q  _" V. T& Q6 g% H$ N7 d' o: k
文件系统创建完毕后, MDS 服务器就能达到 active 状态了,比如在一个单 MDS 系统中:
9 a: ]! h" J7 ~9 `' T* P9 F& x6 X9 P5 g7 i7 M" f1 ^) C
[root@ceph-stroage01 ~]# ceph mds stat
1 C6 R% X, L8 f1 v- a( h6 E4 l/ scephfs:0
$ F0 k  T; Y* A8 C. p- J2 A, Q[root@ceph-stroage01 ~]#
3 A% `7 G2 v8 m: K查看集群监控状态:
3 p* t% v& T; Z. @* }( t) b
! Z" r6 W0 r' L1 m" y5 ~[root@ceph-stroage01 ~]# ceph -s
4 P6 @% A3 l; M; E8 V  cluster:
7 t8 Q- s, Y& J5 i: r$ z    id:     db51539c-d566-11eb-a3e9-e6f1aaf957fd
7 I+ r9 w/ _3 ?# R4 C* O( w    health: HEALTH_ERR; ]+ G. s* [0 t* H
            2 filesystems are offline# B- H/ H, X; C( s: N
            2 filesystems are online with fewer MDS than max_mds5 w3 g3 k5 J* _1 ]9 A4 T
# K* q! j8 @, T
  services:0 A" ^: u# y/ P' ?8 l6 w
    mon: 3 daemons, quorum ceph-stroage01,ceph-stroage02,ceph-stroage03 (age 9m)
- G: _) j( i! a; P8 L3 ?    mgr: ceph-stroage01.cdthyk(active, since 9m), standbys: ceph-stroage03.dtasrq
7 K. r+ A9 F9 F/ {: u    mds: cephfs:0 cephfs_k8s:0
- I) s' ^& u! J$ W) T4 s' U1 L- r    osd: 6 osds: 6 up (since 9m), 6 in (since 2w)
" v# n' }. _3 Y1 `" I0 [. n
5 W" [5 y/ b+ V8 R  V) o9 V  data:
, G5 e# {" O# V# ^- g- u8 q    pools:   8 pools, 201 pgs# V. ]% O# u2 r, W/ K+ H7 v" m$ y1 H. e
    objects: 68 objects, 87 MiB7 m- t5 h# B  d5 S! ~4 I4 N/ k! X
    usage:   6.6 GiB used, 593 GiB / 600 GiB avail
2 Y1 g  R" o$ `8 [    pgs:     201 active+clean
3 c6 s# A0 _# a: {# y1 I[root@ceph-stroage01 ~]#   o9 N8 Y# P# L" ]9 Y8 C9 L
[root@ceph-stroage01 ~]# ceph health detail* C& q, z( x2 @$ G( ^! `; ~
HEALTH_ERR 2 filesystems are offline; 2 filesystems are online with fewer MDS than max_mds
; n& F2 B/ v% C0 @7 g[ERR] MDS_ALL_DOWN: 2 filesystems are offline
/ ]8 L% y6 K- L8 u    fs cephfs is offline because no MDS is active for it.
5 V! A! t! z  o' V    fs cephfs_k8s is offline because no MDS is active for it.* I. ?% \  r: g# Q+ k
[WRN] MDS_UP_LESS_THAN_MAX: 2 filesystems are online with fewer MDS than max_mds4 j* X0 k! T5 M' |
    fs cephfs has 0 MDS online, but wants 14 u. ^) Y  y  _! E
    fs cephfs_k8s has 0 MDS online, but wants 1- Z, ~! V0 x6 A$ }8 H+ Q
[root@ceph-stroage01 ~]#
0 E/ ]1 e& p8 W5 G! z所有的mds都没有active的状态,造成元数据无法恢复,所以此时需要放弃原来的cephfs,重建构建基于原来data池生成新的cephfs.
( |8 D- k. [5 B6 F* v
& r4 {6 C2 D4 R2.元数据故障恢复" E" D& R& L# K+ Q0 a* c: }8 g1 f
step 1.设置允许多文件系统0 D& C' m6 x: v

* b5 v3 g5 E+ u5 x* a7 {ceph fs flag set enable_multiple true --yes-i-really-mean-it
* u- }3 i3 z) G* b7 D7 bstep 2.创建一个新的元数据池,以免损坏原来的元数据; F, b8 ~7 [- q- X3 z
# d- x' o9 r, i: M8 Q1 O
ceph osd pool create recovery 88 y1 X) b2 w, U; P
step 3.将存储池fs_data和新的元数据池recovery关联创建一个新的recovery-fs
8 L7 P" r% R7 {, j6 S# Y
" q* h0 k2 w4 ]5 N( S$ o/ _ceph fs new recovery-fs recovery fs_data --allow-dangerous-metadata-overlay
0 E6 Y; u1 z+ _% }% _$ W8 S+ Bstep 4.文件系统的初始化相关工作
( v& s7 d* h* |+ r3 l) e+ C5 @! D) c
( M5 P9 x  p2 ?/ F9 e* \& ~cephfs-data-scan init --force-init --filesystem recovery-fs --alternate-pool recovery$ g5 m* q. I9 j
step 5.reset fs
1 @8 l) ?/ n: T! g
5 [. v$ _' u% ~9 l. z. o/ Mceph fs reset recovery-fs --yes-i-really-mean-it
- y- v2 [! [* T% `若失败,要把所有mds fail掉或者stop掉,再快速执行上面命令。
% b/ `! V  H$ l. n( g  m  V# o
8 _* X% F! k) ?! E$ |. X4 _5 ~cephfs-table-tool recovery-fs:all reset session
" Z4 B$ Y- T; y- q4 s+ Vcephfs-table-tool recovery-fs:all reset snap+ P! z/ p1 }  l- u0 z% E0 U0 Z- d
cephfs-table-tool recovery-fs:all reset inode+ d6 N7 K1 T6 E+ J. J0 A
出现Address family not supported by protocol的错误忽略掉3 P# |1 c! B2 G* ^9 p

" w/ I; k- c/ U+ Mstep 6.恢复相关
0 E- J; u3 F% n% V确保新建的recovery-fs没有active的mds,有则stop掉,不然该mds容易crashed。, V; A4 Z; k$ p1 Q6 O

; B- n. g* Y6 z3 S! Gcephfs-data-scan scan_extents --force-pool --alternate-pool recovery --filesystem cephfs fs_data7 G7 d5 a, z# x" c
cephfs-data-scan scan_inodes --alternate-pool recovery --filesystem cephfs --force-corrupt --force-init fs_data, ^0 a; J& M3 ]  Z
cephfs-data-scan scan_links --filesystem recovery-fs' d- z" Z! M( c0 m# D0 M- d7 @  |
出现Address family not supported by protocol的错误忽略掉8 D) H1 s& M- i$ A1 Z7 X! B

7 W7 [7 c, G" r/ @* q1 _, _8 b2 Ksystemctl start ceph-mds@node821 O# a. z4 ~. {' ^0 g, y
等待 mds active 以后再继续下面操作: N; z8 k4 N3 u. _, T
% E; a1 ?* y5 p  r/ [6 |
ceph daemon mds.node82 scrub_path / recursive repair
/ {) A% @, x) F$ x* Y; M设置成默认的fs2 [3 b% r+ z0 m6 y/ H& `

! Q! e1 _7 Q  l' Y8 J! E# E* gceph fs set-default recovery-fs  U8 n- B9 ~) H( b- W0 |
可以看到在lost+found里面就有数据了这个生成的文件名称就是实际文件存储的数据的prifix,也就是通过原始inode进行的运算得到的。: V5 ^; G* t+ H
- L* A! c# ?0 i$ O; a
备份原始的元数据信息" f: e4 \9 W  j$ A: G" J" u# e
# w; A8 Z% c* l  ^2 R$ Q' p# Y1 X  a
ceph daemon mds.node82 dump cache > /tmp/mdscache
: L0 h" |, u, ~元数据恢复原理
' U5 c( D; O/ S一般文件系统采用的fsck命令来维护文件系统一致性,但是fsck对cephfs的难度是非常大的,主要原因在于其机制存在根本的区别:0 Z* ^' u' }, q3 f" W+ T$ Q- b: N
8 s  ^% e  j& `, [# ?
cephfs修复的是一个rados集群数据而非一块磁盘设备;9 f; a* ]! P# ~5 C  a
需要精确的识别数据的所有数据片,及这些数据片所属的inode5 C9 ~/ J. l. C7 V
大量的元数据不可能全部保存到内存中  `1 }! I. f' ~
数据丢失原因可能在于
, p0 R2 ~% m2 H1 o(1)系统bug导致;
2 a( ~& t1 T8 ?% x5 }% L! m: r(2)由于RADOS同步的灾难性故障——可能到时大量数据丢失;
% h4 ]. l) o& H" f2 l1 ^(3)bit位翻转(bitrot)
$ g6 x+ n- D5 g. a$ Ecephfs-data-scan" ]( m6 w! Z) P# X- _7 c7 P
cephfs-data-scan根据数据存储池中的内容重新生成丢失文件和目录的元数据对象。
2 G/ _5 u! D- e# _, `1 z$ {step 1.初始化
- H8 }5 w; p" G8 ]. A6 D! ?4 z0 L: y# z; b3 t! D6 o$ p8 b: j# ^( k. M
cephfs-data-scan init
# J$ V8 o% y6 \% l  Vstep 2.扫描所有对象以计算索引节点的尺寸和 mtime 元数据;( L3 N$ _6 w/ t% X5 x( ]( E$ [

  V1 n/ h# I4 F$ _8 m1 ccephfs-data-scan scan_extents <datapool>
+ D, F. s1 M* M- O: G```bash* b, w- t) @& v: g
step 3.从每个文件的第一个对象扫描出元数据并注入元数据存储池。
) d# M1 O6 @5 c```bash6 J  O0 j2 F- ~& N1 |
cephfs-data-scan scan_inodes <datapool>6 T) C+ i) o1 z, _
如果数据存储池内的文件很多、或者有很大的文件,这个命令就要花费很长时间。要加快处理,可以让这个工具多跑几个例程。先确定例程数量、再传递给每个例程一个数字 N ,此数字应大于 0 且小于 (N - 1) ,像这样- L: b* |( k3 }! Q4 Y( @

+ n' b7 B2 ^0 r5 ?6 g+ g4 C1 R# Worker 0
0 [7 x' Z! z. F6 T2 }) j+ f' lcephfs-data-scan scan_extents <data pool> 0 1
& f$ d* A* a3 a8 u% o+ @# Worker 1
; l# ]. w; ?+ L- f* A& Ccephfs-data-scan scan_extents <data pool> 1 1
0 ~# e( m2 O  W$ B- z$ _, b' N# Worker 0
* Y, X; {+ G9 ^2 ]  lcephfs-data-scan scan_inodes <data pool> 0 1. V0 a( T& |' L( z* h
# Worker 1) r4 @* g' s( \  @+ Q4 Z7 t. K
cephfs-data-scan scan_inodes <data pool> 1 1
0 O# J& w* h$ _4 D3 R% T3.mds rank 0 is damaged
, @- A1 i( [! |& r- Z) h/ Z9 ~启动ceph后,出现如下错误:
' w  e( ^) P) b# F7 j: g% [$ o
0 q. ?( i% N5 ?" ^[root@k8s-node2 ~]# ceph health detail( j' K9 N) T; w2 X* }* Q
HEALTH_ERR mds rank 0 is damaged; mds cluster is degraded7 g) r* X3 U7 @
mds.0 is damaged$ q+ D/ z  [6 a, F
mds cluster is degraded
9 F  ?3 a; R! D- J提示 mds.0 不可用。$ }" K3 r) c) I  }: r$ {  |( c# X8 f
在部署ceph时,安装了3个mds, 分别运行在3台服务器上。并且参考官方的配置,使其中一个作为 master 对外提供服务,另外两个作为 standby。来预防单点故障。(max_mds 设置为 2)8 l0 }% d( e0 c7 ^" L# ^
http://docs.ceph.com/docs/jewel/cephfs/standby/#examples
  n! b* x+ r& `2 r
2 o/ y6 _+ R2 H6 {. d该错误发生后,3 个mds,均为 standby 状态。按照官网的描述来看,当所有 mds 均处于 standby 状态时,其中一个 mds 会选举称为 master.
5 ~; G# y9 f1 H8 e& I0 P, S于是挨个停止mds, 随后又逐个启动并查看/var/log/ceph/ceph-mds.xx.log。发现 mds 在称为 master 时,出现了如下错误:
  X6 P9 q3 I" o" f6 ~# k
4 H5 }) {. T- h...
6 m& y7 S: ~) ?" j2017-09-26 11:30:48.976326 7f9ee3941700  0 mds.0.journaler(ro) _finish_read got less than expected (4194304)7 b; a" j! ]; f3 E
2017-09-26 11:30:48.976354 7f9ee1734700  0 mds.0.log _replay journaler got error -22, aborting; H# M8 [! q, V' Y3 h5 |" v
2017-09-26 11:30:49.071230 7f9ee3941700  0 mds.0.journaler(ro) _finish_read got less than expected (4194304). |" V% R; b3 X& r$ m
2017-09-26 11:30:49.071472 7f9ee1734700 -1 log_channel(cluster) log [ERR] : Error loading MDS rank 0: (22) Invalid argument' M. B& y$ c4 L% }/ K1 Y% g
2017-09-26 11:30:49.076129 7f9ee1734700  1 mds.k8s-node1 respawn
, v) W; ?4 w  X5 n) T) k...: }( q, Y0 D8 E% S# s) n- s
2017-09-26 11:30:49.099291 7f99e58be180  0 pidfile_write: ignore empty --pid-file
7 H2 }' P2 d9 ~2017-09-26 11:30:49.571643 7f99dfacf700  1 mds.k8s-node1 handle_mds_map standby" j8 W0 N3 D8 v. c
提示在读取 journal 的时候出现差错,因此可以确定问题出在 mds journal 上。
7 H2 r$ x$ j) Q* M7 Y7 L. R3 l
! N! m( v/ h9 W" U5 D. |  f$ ceph mds repaire 0

0

主题

0

回帖

9

积分

管理员

积分
9
QQ
 楼主| 发表于 2022-8-3 11:51:31 | 显示全部楼层
step 1.导出 journal8 g6 u$ H8 p+ C
在执行有风险的操作之前,先将 journal 备份:$ o! [! }- o; B' K8 Q

- ?8 ^6 Y' a; {1 wceph-journal-tool journal export backup.bin
9 f  L7 F  o4 c3 u* m$ oNote : 这个文件大小和ceph集群存储数据量成正比,会很大" ~/ q$ Z1 u, D+ t( ]  S: t

/ v( h% z0 U# Q& m3 k* Pstep 2.从 journal 恢复
: i; M. `3 Y. V' C2 ?% o当 mds 因为 journal 损坏或者其他原因无法读取,为了恢复文件元数据可以执行:3 Z' q4 z% Z3 ^9 j0 \7 t' V! b6 q
3 w% y3 t/ w& Q
ceph-journal-tool event recover_dentries summary
# B2 E5 w! l5 @( ^默认会从 mds.0 中恢复, 使用 –rank=<n> 来指定其他mds$ ~* Q" D% d4 j
8 A& Y9 S4 d' _& |! g
这条指令会将 journal 中所有可回收的 inodes/dentries 写到后端存储,前提是要写入的 innodes/dentries 版本比后端存储里面的要高。 如果某个区块的 journal 丢失或者损坏,那么就不会被写到后端存储中。1 X$ u( U$ l. Z# x/ W9 k- K) g/ d; H
# [5 U) N' ?! U1 b4 n0 l+ q  [
Note: 除了将inodes/dentries 写入之外, 这条命令还会更新每个 MDS 的 InoTables, 标明被写入的 inodes 号在使用中,在一般情况下,会让后端存储恢复正常状态。
" j8 k7 _5 B' M" t/ H
& S! e6 C' A/ h4 w5 d$ `3 M3 V% k; l0 _1 b/ ]此操作不能保证后端存储的状态达到前后一致,而且在此之后有必要执行 MDS 在线 scrub。此命令不会更改日志内容,恢复了能恢复的部分后应该把journal截短。
' \3 N3 ]; [% X+ K" a% r4 f7 n% N% c9 n9 h& J9 S8 ]0 R4 Q. z
Note : 然而在执行这个命令之后,集群并未恢复正常,因此还需要往下看
7 n/ G4 L- o6 {" ^0 ^4 g9 b  q' ~5 \# R3 O. T, D5 g3 {
step 3. 截断日志
6 ~1 X/ v/ o# l3 k0 t( M
) z, p# H! Q) D3 k7 w, Kcephfs-journal-tool journal reset
9 O& z, x" E+ b# v# s# j重置journal 将会造成metadata丢失,除非你提前通过诸如 recover_dentries 的方式将metadata保存。该操作可能会在数据池里面产生一些孤儿对象。这会造成已写入的inodes再次被重新分配, 权限规则可能因此被违反。  ?! T2 o6 o! Z" I8 F
) H6 k" m; a( j
Note : 有个类似的 issue中也提到了上述步骤(link),但执行到这一步后,就没往下走了。
9 @6 ~+ ]5 `4 w! e7 P! PAnd mds rejoined again and everything seems to work fine now. 这点我没验证过,担心会有隐患。于是按照文档步骤继续执行了。5 L/ r& X( k: }4 T  n" }; t) Y
) F' H: q1 W5 x3 J# {% G3 d$ L
step 4. 清除 MDS 表2 d. S7 T3 d' P" T) K
在 journal 被 reset 之后, 它可能不再符合MDS表的内容(包括:InoTable, SessionMap, SnapServer). 重置 SessionMap (即擦除所有Session) , 通过命令:
! E8 I' n: m5 P, o, g6 X) W
9 ~9 t+ ~. m, {cephfs-table-tool all reset session7 ?! s4 A/ U) \3 T8 Z! N+ D
这条命令会在所有mds中生效, 可以将 all 替换为指定 mds 标号。
4 _+ v, a2 n" Zstep 5.MDS MAP RESET
6 \; p% N' w3 D( \5 w0 Y5 D4 V一旦文件系统底层的 RADOS 状态(即元数据存储池的内容)有所恢复,有必要更新 MDS 图以反映元数据存储池的内容。可以用下面的命令把 MDS MAP 重置到单个 MDS :9 ~: q' b) L+ R/ Z# w3 I
# ]( G1 B  g  C& h$ z/ k9 I+ l
ceph fs reset <fs name> --yes-i-really-mean-it
) D$ J8 Y0 Z4 @. n1 O运行此命令之后, MDS rank 保存在 RADOS 上的任何不为 0 的状态都会被忽略:因此这有可能导致数据丢失。$ m& P' L6 d7 x8 }
- V/ [- }0 J; _5 J
Note : fs name 可通过 ceph fs ls 查看/ P% i- ]9 q% {$ Q4 R( E; c' u

" ]/ Z. F- ~$ ^step 6. RECOVERY FROM MISSONG METADATA OBJECT: h% E! U" n0 o2 F' M

+ m' }9 X! |) C. F" o# Session table3 a$ d7 Y1 L" A% t
cephfs-table-tool 0 reset session. g7 ^) S; z/ l3 l" W7 w1 E
# SnapServer- k& j1 [: i( E3 W+ y( ~# S( ~1 e: |" c
cephfs-table-tool 0 reset snap
1 m$ i- i3 k0 H- J# InoTable: W" Y' D- i$ l0 ^+ H: I
cephfs-table-tool 0 reset inode2 S  A# ~" j( e% T: n8 N
# Journal
& P( L2 @2 M  v& I5 J  tcephfs-journal-tool --rank=0 journal reset6 o0 l/ W4 ^* M
# Root inodes ("/" and MDS directory)
4 W6 ^2 [, A- Q9 H( ~  wcephfs-data-scan init
0 T$ q, e$ [% k5 c最后,会基于数据池中丢失的文件和目录来重新创建 METADATA OBJECT。分为2步。
# g" h' B( {+ N# C5 ~
0 t" a. w) `) {! P7 l, z扫描所有对象并计算出inodes 的大小和 mtime metadata
3 I0 ?% z, w) C- d  S; r; _  f* O2 Q+ ?$ J
cephfs-data-scan scan_extents <data pool>& T) j& J: r. B- _9 Q
扫描每个文件中的第一个对象来收集METADATA,随后注入到 metadata pool* ]/ j: q+ S3 D" X7 @1 x- W

9 z+ E- T4 @. K) A5 u6 y' C4 wcephfs-data-scan scan_inodes <data pool>
: s$ t7 _8 B7 d% M4 uNote : 这两个步骤太耗时了,应该考虑起多个workers来同步处理。data pool 可通过 ceph fs ls 查看, o' r" a) P. N- r6 Z( L! m; \

7 u1 a7 Y2 x: b- a9 {; L) P# Worker 0" [% y5 j% ^( }
cephfs-data-scan scan_extents <data pool> 0 1
6 r0 R, S. `2 t5 s4 s1 _# Worker 1
: c, n$ I% |  g6 T* E* Dcephfs-data-scan scan_extents <data pool> 1 1
) ?$ V* C( f+ U) }% _# Worker 05 p0 a/ s8 W5 W' j, L7 }  V0 K
cephfs-data-scan scan_inodes <data pool> 0 1
9 j" R( r- k6 ]0 f8 X* `8 d# Worker 1
- \( c! R; D4 ~5 |' V+ {cephfs-data-scan scan_inodes <data pool> 1 1
( L6 @9 J2 e* D- Q! r. E8 y- lNote : 一定要确保在所有 workers 完成 scan_extents 之后再进行scan_inodes操作。==! K" ^) J. D" d6 w5 G4 Q2 n

( X+ Q1 v0 W# ?( B待所有操作执行完毕之后:3 a6 d* O7 ^9 F9 v3 n5 U% _
& y8 c* p! X& P1 c
[root@k8s-master ~]# ceph -s
0 L* [9 Z: w3 A% |$ N# Q    cluster e61d687d-f43d-4f50-af66-da96e5856be9
. G) Q6 G$ B  _7 o" E0 q! Y5 H     health HEALTH_OK' v$ T& h; p' h% L" a
     monmap e5: 3 mons at {k8s-master=172.16.18.30:6789/0,k8s-node1=172.16.18.6:6789/0,k8s-node2=172.16.18.7:6789/0}
' K0 o  V9 b5 }+ S4 _! n            election epoch 676, quorum 0,1,2 k8s-node1,k8s-node2,k8s-master) _% }8 V  c0 c! o; O
      fsmap e4970: 1/1/1 up {0=k8s-node1=up:active}, 2 up:standby) Q* F9 q& y% b6 j
     osdmap e2914: 6 osds: 6 up, 6 in, q8 X+ s0 V0 f5 g* @" L4 V
            flags sortbitwise,require_jewel_osds  B! U9 \  ^, u& G; O' W% ?/ K: E
      pgmap v10110565: 256 pgs, 4 pools, 25575 MB data, 372 kobjects
; s( `( [- k& L3 h- g/ `: P) h. s            58730 MB used, 11115 GB / 11172 GB avail
/ a( l$ s0 Z: D; Y5 g+ g                 256 active+clean

0

主题

0

回帖

9

积分

管理员

积分
9
QQ
 楼主| 发表于 2022-8-3 13:37:30 | 显示全部楼层
[root@ceph-1 ~]# ceph fs dump
4 O' I# s$ G/ }dumped fsmap epoch 135
1 m' r: y- q8 E1 ?5 _# Q8 r2 R- fe135) R2 J6 Z4 A) ]3 @5 m
enable_multiple, ever_enabled_multiple: 1,02 i- Y7 J* f4 k) B2 @" C  |4 z( p
compat: compat={},rocompat={},incompat={1=base v0.20,2=client writeable ranges,3=default file layouts on dirs,4=dir inode in separate object,5=mds uses versioned encoding,6=dirfrag is stored in omap,8=no anchor table,9=file layout v2}
) S- a$ [6 z8 L9 `2 @9 t5 b; x* Slegacy client fscid: 3
- P( \$ }% d# A" `1 p
, l; {3 [- E" P7 j; iFilesystem 'filefs' (3)
7 F+ @! c5 q5 w0 K3 m* ]. sfs_name        filefs
; d0 R. b; W$ q0 n6 fepoch        135" O  N. H$ T' p+ D
flags        c* m: ^7 j: X8 B8 d' v4 A6 s
created        2022-07-27 11:43:28.8894881 g8 I; r( s# W; h3 g
modified        2022-08-03 10:23:42.1734449 U  B7 |. G* o7 ]0 x$ C1 \0 ?; @
tableserver        07 h/ X0 J- s! x; q2 Y1 i$ j
root        0/ W0 b) A5 l$ e6 M6 J5 ^" k( G
session_timeout        60
- x7 p5 Z% L2 X5 k9 \; `! osession_autoclose        300
' ?) L% @; W4 e" P4 N0 _max_file_size        1099511627776
6 Z$ c8 t) m  D+ T3 [0 Q5 Nlast_failure        0& {9 i7 O& e0 H9 E  S
last_failure_osd_epoch        3864 n7 T) j# ^) T7 J& e" P3 _) O
compat        compat={},rocompat={},incompat={1=base v0.20,2=client writeable ranges,3=default file layouts on dirs,4=dir inode in separate object,5=mds uses versioned encoding,6=dirfrag is stored in omap,8=no anchor table,9=file layout v2}8 {$ m, H+ _" u+ }) ~8 _
max_mds        13 h" B3 [. Y6 y
in        0
& J2 G5 U7 h8 K7 o5 q" X( V+ uup        {0=84099}- e/ ]& t# f' @% s6 ]7 [1 ^. v8 y8 h
failed       
: ^3 l  J& G2 f" w/ q' @damaged       
/ a5 o% m2 W, g4 F6 ]& |6 F! bstopped        1 J  \" m$ b0 e* p5 B
data_pools        [7]
7 R/ E; u5 p. E. a. x: _metadata_pool        6- y- N" E6 B2 ~$ `2 v  f
inline_data        disabled
' I7 [, o5 q4 U9 Z1 Vbalancer       
1 w7 J! c, z( d$ jstandby_count_wanted        1& E: B2 s3 m6 D
84099:        192.168.120.31:6800/2291079756 'ceph-3' mds.0.117 up:active seq 40
) e% p' U; w$ k& L$ \7 ^1 ]6 M% d
% r1 i( P, _  M4 V( l+ `/ q
- C' L7 o: J" v4 l7 k5 i; N. y/ @/ |Standby daemons:
$ _4 [. S9 _' p, i  N
2 J  C/ I* y9 Q0 X0 j( b5 i84111:        192.168.120.16:6800/463439748 'ceph-2' mds.-1.0 up:standby seq 2
8 K/ \$ Y) C$ l6 D/ R# H84120:        192.168.120.23:6800/4181220800 'ceph-1' mds.-1.0 up:standby seq 1

0

主题

0

回帖

9

积分

管理员

积分
9
QQ
 楼主| 发表于 2022-8-4 13:39:30 | 显示全部楼层
1、前言7 O& |4 x+ R  K9 x  X3 V
这里实验在使用cephfs时,如果cephfs的元数据损坏或丢失了,那该如何恢复出用户数据。下面就为大家演示下如何恢复。1 H7 d0 S* ^$ c
; t' P8 S( z3 _- Q8 w8 j& E7 r
2、准备测试环境
# D  B' n6 I7 O2.1、准备测试集群
' B, ^# S' Y, t3 |8 z我是基于L版本做的实验,J版也是可以的。测试环境如下:& B7 |' T7 y! w5 G" i- b9 u

+ l7 n/ }' i1 G2 U8 _[root@ceph05 ~]# ceph -v
6 F# z: u2 J9 g5 Vceph version 12.2.11 (26dc3775efc7bb286a1d6d66faee0ba30ea23eee) luminous (stable)& Z3 l, H8 _0 Y' {* B' ~
  j2 Z: d5 E6 r; \) L) P! @
[root@ceph05 ~]# ceph osd tree
' B4 T5 i) [4 fID CLASS WEIGHT  TYPE NAME       STATUS REWEIGHT PRI-AFF
' r0 b6 b+ e( V- b& v-1       0.07397 root default                           
& |6 b1 \; A) I" d-3       0.03699     host ceph05                        
, a. c* Y8 W) } 0   hdd 0.01799         osd.0       up  1.00000 1.00000 2 R5 t) y- H8 C* C; s
1   hdd 0.01900         osd.1       up  1.00000 1.00000 5 {# I2 y$ j5 F
-5       0.03699     host ceph06                        
2 i0 W1 \2 Y+ E 2   hdd 0.01900         osd.2       up  1.00000 1.00000
; R* _& G  ?% z5 K 3   hdd 0.01900         osd.3       up  1.00000 1.000007 w9 A1 L$ t: r: g8 u7 }% D. |+ N
+ g/ Z; U" x8 p! X$ X% W  e
[root@ceph05 deployceph]# ceph -s
+ F, L( {! X% A' o& d& J  cluster:
0 y# c! d% X# I2 [( u4 P    id:     176feab8-ca22-47bf-b809-202deac53c6f% p6 S# q3 }# e# k
    health: HEALTH_WARN) K# y' r& ~6 ~7 T$ K% p
            crush map has straw_calc_version=0' U4 n; s# T/ k  ~" ?' Y% s
9 C2 Z9 i$ f0 |
  services:
9 q2 W! c4 c/ |3 Z: D% `3 d2 ]" E    mon: 1 daemons, quorum ceph050 Q5 V9 S- N4 y: d
    mgr: ceph05(active)
2 y( o3 U' t( s" A    mds: cephfs-1/1/1 up  {0=ceph05=up:active}- w& l" T+ n# X; k" h. t
    osd: 4 osds: 4 up, 4 in
$ I+ _: d$ D  f0 F& _, H) z( l2 d; a/ S4 j  ^- A
  data:
  {+ P$ ]! A+ U# |9 ]7 r' a+ N    pools:   10 pools, 304 pgs
& c' d! H/ w" y    objects: 918 objects, 2.60GiB
- G; F& E, d$ h, v    usage:   6.70GiB used, 71.3GiB / 78.0GiB avail* }# z3 M, n5 B
    pgs:     304 active+clean/ a( A7 [! l) `1 s) K' U
2.2、准备测试数据1 T$ [# s5 B* O, D
挂载kc
- H4 o) c+ [! Y; F) P  M0 D& C! S: ?, X8 j$ a0 K8 |
[root@ceph05 deployceph]# mount -t ceph 192.168.10.30:/ /cephfs
8 {( u- g4 C5 x7 u; r( i+ n[root@ceph05 deployceph]# df -h|grep ceph# z% S2 y7 A7 f! K3 @, s6 c) w
···
/ r# {' d! t0 C) P# e192.168.10.30:/           78G  6.8G   72G   9% /cephfs0 T6 ^7 d7 y& g9 f0 J
···+ a: y. A$ f6 `' n8 \
写入数据(这里我写入了几个比较有代表性的文件类型:txt、jpg、png、pdf、word、excel)- ^5 O( Q9 R* ~& A6 C

5 a% b+ k$ V# r1 X[root@ceph05 deployceph]# ll /cephfs/9 y3 l. G4 S, f
total 5912
: F% j: Y4 Z' r& O* K& B. v-rw-r--r-- 1 root root   31232 Mar 15 12:18 111.doc
) B0 f" k8 \7 d  }4 C9 k-rw-r--r-- 1 root root   20593 Mar 15 12:18 22.xlsx
) [( ^: r7 |4 b-rw-r--r-- 1 root root   12494 Mar 15 12:17 5be23a3eec2c0.png
! U1 }9 R, b8 T. ]% H- Y; H0 |-rw-r--r-- 1 root root    3189 Mar 15 12:17 cmap.txt& i) p0 {0 u! A
-rw-r--r-- 1 root root 5985243 Mar 15 12:17 hello0.pdf- z" c2 n1 g/ n* Y& p0 Q
3、模拟故障, ]0 ~" e; b3 [( J0 j) u
这里直接模拟元数据丢失的情况,删除metadata池里面所有的元数据对象:0 Y4 u/ U- f6 A7 D8 n& d5 e

+ H/ k: O! Y. t& L! o  s  G[root@ceph05 deployceph]# rados -p metadata ls|xargs -i rados -p metadata rm {}
+ _; @8 H: `8 i5 q( @% S[root@ceph05 deployceph]# ceph df- [! |: i, V. X) Z
GLOBAL:6 E: s$ E* ]+ c, r* `( p% ?+ {
    SIZE        AVAIL       RAW USED     %RAW USED , }5 `& j# ^5 h0 Q; v8 N3 G! a
    78.0GiB     71.3GiB      6.71GiB          8.60 / Z$ X0 U0 {* Q
POOLS:
$ J; C. e  I9 e6 G% V7 U    NAME                          ID     USED        %USED     MAX AVAIL     OBJECTS / u5 ~3 r6 {$ F2 L
    .rgw.root                     1      1.09KiB         0       63.3GiB           4
) x9 h% j* K4 u  [% x    default.rgw.control           2           0B         0       63.3GiB           8 % P: `( ^: J9 }, m- R. @& ]# t" Y
    default.rgw.meta              3         720B         0       63.3GiB           5
7 i/ V. K$ C( y( @+ H    default.rgw.log               4           0B         0       63.3GiB         207
$ U) \) H8 r% Y9 k9 `9 ?    default.rgw.buckets.index     5           0B         0       63.3GiB           1 / {# F, I1 G" B" {1 W
    default.rgw.buckets.data      6      1.02KiB         0       63.3GiB           2 ! b/ f7 \, y) J: [( b- F) v- S
    pool01                        7      2.60GiB      3.94       63.3GiB         666
+ Q4 g3 i1 j$ z1 h# O    rbd                           8          36B         0       63.3GiB           4
+ A! j/ Q7 Q. H1 v( q# c! h2 H# ]    metadata                      17          0B         0       63.3GiB           0 " d& F" `1 B& K4 ]  ~
    data                          18     5.77MiB         0       63.3GiB           6
' d2 _5 v3 ?- \7 l看到metadata池里面没有对象了已经,重启下mds看效果,因为mds里面会缓存元数据信息,所以要重启下mds:
5 F0 q) a0 m/ i/ v! _* G% |" J) ^; O6 B7 Q+ `% z* T  O
[root@ceph05 deployceph]# systemctl restart ceph-mds@ceph05
# z% A' x( K9 s  Q/ K9 k0 \4 m3 \[root@ceph05 deployceph]# ' {1 v) S. L: u$ s& d& m( v
[root@ceph05 deployceph]# ( a2 M  J8 @8 B0 B; }! n. M
[root@ceph05 deployceph]# ceph -s  F. N+ r5 z8 V
  cluster:
( b5 B  S& u3 W/ J4 o, o8 b7 M    id:     176feab8-ca22-47bf-b809-202deac53c6f
  Q9 |. N3 B+ }7 {; F4 ~; ?    health: HEALTH_WARN
" P# J2 E7 d1 g0 O6 f            1 filesystem is degraded
  Y6 Q6 }/ f: R: e9 T! F3 ~: X            1 filesystem has a failed mds daemon
' D8 `7 h$ [0 n. O            crush map has straw_calc_version=0
- ~% F0 t* _3 f& L8 v
1 Q7 T) X6 v# g! K7 b  services:* F1 ]- L/ P( n& R* s
    mon: 1 daemons, quorum ceph05
7 C% |" ?2 c* M4 r    mgr: ceph05(active)
- B2 y* A6 f: \& R: u    mds: cephfs-0/1/1 up , 1 failed  h5 \0 j+ O4 |. K/ q( D# k
    osd: 4 osds: 4 up, 4 in/ ]0 G5 h& x# G& {% x8 B# I3 p! c
+ ^( p8 M6 u( k+ A9 c1 M* X  t* \& [
  data:5 D4 `' Z$ |, c5 I/ k& o
    pools:   10 pools, 304 pgs
& r4 |# g" f. y' ~    objects: 905 objects, 2.60GiB# F6 \) ?4 I. Q3 n! ~
    usage:   6.71GiB used, 71.3GiB / 78.0GiB avail
2 \6 i2 s/ u0 k* A' P2 W7 F    pgs:     304 active+clean$ w; }- T1 _& b3 _3 h( ~
看到集群现在不正常了,访问kc里面的数据卡住,说明数据已经无法正常读取了。# q" Q9 h! ^" Z% [/ H+ S: C3 {
) B) _! B& q, U6 g
4、开始恢复* a# ]/ R# b/ p
使用我编写的py脚本(文末给出了源码)恢复,把脚本放到集群任意一台节点上执行:
0 k6 _1 H, n7 |
; v0 ^! X  ?& v  Z( b% {[root@ceph05 rcy]# python recovery_cephfs.py -p data  a# q3 C; h/ L8 a9 i  h2 W4 V/ o
-p指定cephfs的数据池,运行完之后会在当前目录下产生两个文件夹和一个运行脚本的日志文件。& |* n  y. t1 N

5 ]" ]0 C# I' y; k$ ]+ C[root@ceph05 rcy]# ll3 l# G, h. s5 ]/ m% g5 [/ N
total 16
9 [2 @* \+ b8 V, d-rw-r--r-- 1 root root 3826 Mar 15 13:57 recovery_cephfs.py
; n6 n$ H5 a% k) z; ?drwxr-xr-x 2 root root  120 Mar 15 13:57 recoveryfiles
3 G; T+ P7 i- ^- P-rw-r--r-- 1 root root 4804 Mar 15 13:57 recovery.log" u* @, G" m( y) C# C9 Z
drwxr-xr-x 2 root root 4096 Mar 15 13:57 recoveryobjs+ J# _( I1 c: f& R2 ?9 p# [6 u
查看恢复出来的文件在recoveryfiles文件夹下:6 r2 E% x" H3 q1 H

/ y1 L; b9 G' I3 M" |) {[root@ceph05 rcy]# ll recoveryfiles/( ^  i- y8 O# Y5 h  B9 ~1 Q! j
total 123645 Z; r$ z. X' ?' B
-rw-r--r-- 1 root root 5985243 Mar 15 13:57 10000000000-pdf. X  b& T2 W$ G8 d4 ?" a" @
-rw-r--r-- 1 root root    3189 Mar 15 13:57 10000000001-text& u5 C# y- S5 s6 o+ n% c8 ^
-rw-r--r-- 1 root root   12494 Mar 15 13:57 10000000002-png3 j4 Q  w% R7 U# T: w
-rw-r--r-- 1 root root   31232 Mar 15 13:57 10000000003-text
% p! D8 D7 t# W3 o, T+ }. s% H-rw-r--r-- 1 root root   20593 Mar 15 13:57 10000000004-excel
9 u- O5 l  g% B$ s文件名格式为”文件在cephfs里面的inode-该文件可能的类型“。恢复出来的文件名后面会给出该文件的类型。这样就可以使用合适的软件打开该文件来验证文件是否完整。
# h2 o2 j5 t$ W3 T, o
! k% Y  v" r2 ~2 Y& j5、总结
1 R, h0 A# T2 a' p8 @3 m! y在cephfs文件系统的元数据完全损坏的情况下,只要数据池对象不丢失,就可以恢复出完整的数据。恢复的思路如下:% \, m$ _/ Q, i% `, M4 y3 `6 j
) A& h; J  e1 Z+ v- u
获取数据池对象
/ |: _- I/ @9 \' f5 Z根据inode找到该文件的所有对象' U$ e" Y& t" N2 q/ h
拼接对象
+ g# Q+ t' G# Y3 y8 J4 d. y9 k' N使用脚本注意事项:
! g& R/ Z# {5 g! M* n0 ~9 x
" x8 p. t# n8 n现在的脚本在只加入了txt、jpg、png、pdf、word、excel这些文件类型的识别,需要其他的就需要自己加入到脚本里面了( p8 c. ?' @+ r4 e
只适合副本池  y+ b3 Z3 M) ~0 A8 G
如果数据量特别大,不适合使用脚本,不过可以参考脚本的思路去一个一个文件恢复
) |" _& \: n3 r1 ]% b( N6、脚本
! v# S! d) t$ a! r% q# coding: utf-85 z1 e6 \; d7 Z! t* `
import os& K! D0 |$ s2 s( F. A5 R9 B3 ?% E) L
import shutil# V+ F6 Q8 s( h' q
import json2 e3 w7 ^3 h) `0 B, N/ x! Z
import sys
! g3 U: {7 p& _: s9 y4 [- d4 ?import subprocess
; r3 w& e8 E! q3 i2 C  p9 f! P- cimport copy! u/ R- s0 @% ^; A) s
import logging, j' H1 G4 `8 u2 A. i4 |
import argparse6 i3 E9 y$ d7 e) M+ w+ D, e

& m+ \+ k3 [, X; A2 S4 |6 [__auth__ = 'ypdai'
8 {- \, `+ U/ n% p$ M2 u6 E* @- `3 `+ X' f8 W; u& E# D0 C
SLEEP_INTERVAL = 1. G4 T5 V1 h$ c8 d- {
logging.basicConfig(filename='./recovery.log', format='%(asctime)s : %(levelname)s  %(message)s',
) }* `3 n6 h' x8 t; h. m                    level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S')8 X, ?* A  q$ D! z" l, W
% G: E% H4 ?8 {6 ~# D6 T1 ~
BASE_DIR = os.path.dirname(os.path.abspath(__file__))+ i0 t9 W) O6 w3 p
RECOVERY_OBJ_DIR = os.path.join(BASE_DIR, 'recoveryobjs')0 z; z- _9 g' _- W8 J) N9 N
RECOVERY_FILE_DIR = os.path.join(BASE_DIR, 'recoveryfiles')
2 r; ~  d6 x+ u% ~% m
+ i# |" g' m$ ?2 A. O/ X0 Y4 C9 {
/ v8 G2 y5 a# j$ B2 {% [def exec_cmd(cmd):
: U. u" w& a8 r    """
/ G/ z& R% O/ e+ L- g    执行shell命令,并返回标准输出和执行状态码
- m  `* t7 O8 ]4 ~* R  i    :param cmd:
6 p. ]6 Y* V6 D5 V  ]1 M2 w    :return:
  C3 W  {: ^/ E6 c- w5 k    """. F5 i) F2 ^% o) l( [
    logging.info('exec_cmd():: cmd: {}'.format(cmd))/ a2 E( o6 I9 Y: r
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)4 R4 W/ f' m0 }$ }& s5 b3 F" I1 a
    p.wait()
; b2 r. K: R9 u; ]5 ~    out = p.stdout.read()
. E/ b+ N! a, x* F# q: g4 I: F- m    code = p.returncode
5 y+ T" _0 R/ m3 I/ i    logging.info('exec_cmd():: cmd exec out: {}, code: {}'.format(out, code))
* H1 }4 g5 P, \" [: ~$ e' c0 c% s    return out, code
& r0 B# ^. u% `8 v  L% ?
& m: C3 E3 V$ o: _7 o+ d* P1 j' p5 e5 X1 J
def prepare(pool_name):
# J# l9 I; B) f  F    """/ @7 Z3 X& `* T+ s' ^: U( w) c$ w! {
    准备恢复条件- n: A9 ?3 J! p) i4 Y
    1、检查所给pool name是不是cephfs的数据池9 Y/ U7 m: @' U* t
    2、创建recoveryobjs和recoveryfiles文件加  y8 D# y5 z$ R6 P1 ?
    :param pool_name:
; u! H$ r' P) I  z/ U* ^' b    :return:
$ n1 f$ w% r/ G3 i3 A    """
+ A5 t: ~3 z5 X1 B8 Z    cmd = 'ceph fs ls -f json-pretty'
& m; I0 X: {4 s: {" x: ?7 P" E% z    out, code = exec_cmd(cmd)
4 \( |) M* @/ ^% j& I7 _: O2 i$ F    out = json.loads(out)
- P7 t+ M& {0 Q8 {* J( v6 [    for cnt in out:4 p# I1 Y$ l0 w8 h+ Q5 Y: h9 U4 m
        if pool_name not in cnt.get('data_pools'):
3 j6 u" t' Z. w: p: Q6 z- R9 o, J            return False4 x; _; v" M- K: C$ g/ j1 \. W

0 \) }' X2 C' T    if os.path.isdir(RECOVERY_OBJ_DIR):
. B0 l5 Q+ L7 J5 f4 w        shutil.rmtree(RECOVERY_OBJ_DIR)1 Y: j, E4 H' z- A) v4 ~& `2 r
    os.mkdir(RECOVERY_OBJ_DIR)8 ^9 w( [; d+ f. ?) \

2 j6 A$ ?) n6 u& H1 q    if os.path.isdir(RECOVERY_FILE_DIR):
# i7 c; \2 l* L6 V        shutil.rmtree(RECOVERY_FILE_DIR)
  G* M% _0 q+ v8 Q# j( c    os.mkdir(RECOVERY_FILE_DIR)  W0 b9 w- V, F
- a' a: j; o9 T% C3 `( O& r% o* R
    return True
* R- Q0 T9 u4 \& _3 f9 F4 w8 Q( K+ n% F% t. A
% z/ w- B: l% Y- F
def get_file_type(file_path):% j& j9 {  V2 l( C, t$ Z- m4 e9 @
    cmd = 'file %s' % file_path% b) n9 C4 f9 B5 q- `2 h
    out, code = exec_cmd(cmd): K' p9 B8 N# Y+ e: H- C
    out = out.split(':')[-1].lower()" S, x5 w* r8 c' G- A: U+ d

/ j( o% R0 y7 a, I    file_type = 'text'3 @, B: @% q+ Z2 V) j
    if 'word' in out:
- j0 k, t4 Y4 @% a1 R        file_type = 'word'8 t: v4 _$ v% P! j& r6 `* U; a
    elif 'excel' in out:
* v. r$ `8 w/ n: s# Y        file_type = 'excel'2 I& o3 R" l/ Z( V! h0 b
    elif 'pdf' in out:- P$ b. ^( F1 C6 \0 y# q
        file_type = 'pdf'
- U5 l1 K& K4 g) W* J    elif 'text' in out:* o. u+ d! L. Q( U
        file_type = 'text'" Q' W8 g; v# _/ p
    elif 'jpeg' in out:
, s' A; k. ~* b4 s' d' _        file_type = 'jpg'
6 k% F$ f) v! @( }' D    elif 'png' in out:
% M0 c5 f8 P- l) Q* T6 H3 X' i        file_type = 'png'8 T) ]3 w( ?0 L9 f, T7 B
( ]/ }8 X' }- Q
    return file_type
9 B( e7 `& d( [, E( F
6 B+ h' n& l/ }, c0 k$ d0 O+ H. |, W
def do_recovery(pool_name):
  i6 f* A4 e1 W0 S8 t    """
# n& S/ j3 W0 p" e    具体执行恢复,大概恢复逻辑如下:
& i. @% F' _8 \% x, y3 p    1、从数据池里面获取所有的数据对象
1 t( A, p7 P' ?$ a# K2 |- `, a    2、找到每个文件的head对象,然后把数据这个文件的其他对象内容写入head对象里面
" V" U( Z- k7 W* O/ Y( {: ~    3、根据head对象的文件类型,推测该文件的实际类型, P) H+ e8 k' P& o1 E
    :param pool_name:
8 d3 p# x8 y6 G7 p    :return:
" Z, p! y' f; j% h    """6 K1 Q/ e4 y6 k+ T( k  m
    cmd = 'for obj in $(rados -p %s ls);do rados -p %s get ${obj} %s/${obj};done' % (
! E. w: ]8 S( ]2 }$ J* l- k( Q        pool_name, pool_name, RECOVERY_OBJ_DIR)& c3 M! f. A5 w& i$ j# s8 ~% c
    out, code = exec_cmd(cmd)
: U7 {2 J# j& i7 k7 p# k
" h' S' {$ [% \. Z' ]    if code != 0:
1 j' I  b: w0 w2 A  T& B# O        logging.error('do_recovery():: get obj from rados failed.'); V* Y% R' t9 O% d; x5 r# W3 P
        return
( a' E+ B1 U1 M% J4 Z' P# u
' a, p4 Z1 Q9 w7 A4 o( C  V! |. V    cmd = 'ls %s' % RECOVERY_OBJ_DIR2 p$ I' b' C- f: L6 S, d& G& M
    out, code = exec_cmd(cmd)8 A/ |3 c% d9 e
    if code != 0:: [5 `) j) h2 ~$ Q' j
        logging.error('do_recovery():: list obj failed.')9 K* K* q# w4 u0 j: R" a" f, Q5 P
        return4 W0 V- j: f* `+ }% L& |8 Z9 c5 F
! J) O; g1 c$ P" o8 }" o
    done_lst = []$ U! c1 r5 W2 f, p
    objects = out.split(), m5 Q( q' o% W. j( j. }
    for obj in objects:# |( n% G, ?8 b5 t& Z
        inode, number = obj.split('.')
7 A# j- y' S& ^5 W" v" _        if inode in done_lst:" U, l- x9 r6 V% d/ \, B
            continue
7 M& S" V& O% z
9 N$ ?2 P5 x- u$ h; K7 m        cmd = '''ls -l %s | awk '{print $NF}' | grep ^%s |sort''' % (RECOVERY_OBJ_DIR, inode)+ ~, r5 t* g, v9 Q- R: k
        out, code = exec_cmd(cmd); D% ~1 [3 S- L1 U. B" S
        files = out.split('\n')5 r# s; @3 ^7 x5 M
5 |3 w9 B3 m( O$ @5 z5 z/ _
        head_file = files[0]8 R8 h* p/ t% h  o; S# f& [8 D0 |
        file_type = get_file_type('%s/%s' % (RECOVERY_OBJ_DIR, head_file))
0 e. @' x6 w* B, q8 E- E5 S        cmd = 'cp %s/%s %s/%s-%s' % (RECOVERY_OBJ_DIR, head_file, RECOVERY_FILE_DIR, inode, file_type)( m! [6 A& {$ J  N& E
        out, code = exec_cmd(cmd)! ^9 v) z  r  T+ g. |
        for f in files[1:]:
8 C6 F' I  H7 ?3 ?            if not f:/ b2 }, A2 I7 t8 H5 v5 V1 v
                continue9 U' [  q3 l( z0 U$ O
            cmd = 'cat %s/%s >> %s/%s-%s' % (RECOVERY_OBJ_DIR, f, RECOVERY_FILE_DIR, inode, file_type)
( H2 R/ K+ O. f# t            out, code = exec_cmd(cmd)" S& t  H. x/ @  S: N
8 x6 `+ P" m" N  }
        done_lst.append(inode)
! B% |# z1 {- `/ [  I
+ N- X2 j, K, Z: Y" u/ x7 a, k. r* y# F
if __name__ == '__main__':. d+ Y& a- J1 ~1 V" N9 t6 W
    parser = argparse.ArgumentParser()
+ t6 S# X) k) n6 Y/ E8 e3 L2 {    parser.add_argument('-p', '--pool', required=True, type=str, dest='pool',, ~$ F2 L4 h& G" ]8 C5 E
                        help='select given cephfs data pool by name')
/ g* Q( x! P2 L$ a    args = parser.parse_args()
- I% y  [4 d' o* l0 u
$ `% x6 l  g) w' v( ~3 e' c8 H    if not prepare(args.pool):, ~) N& @" b, S. n2 A
        logging.error('main():: invalid pool name.')
. p- x3 k" ~% Q; Z        sys.exit(1)
7 H: Y$ [: S+ o: P% a. M$ U) P) \3 J( |9 {' `4 X% O% {$ Y' V! L. h
    logging.info('=== main():: recovery start')
& u$ W: h0 |( W( p    do_recovery(args.pool)7 D7 L: C& q5 j  S3 U0 [; S5 h
    logging.info('=== main():: recovery done')
您需要登录后才可以回帖 登录 | 注册

本版积分规则

返回首页|Archiver|手机版|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )

GMT+8, 2026-6-11 22:56 , Processed in 0.018747 second(s), 23 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表