Linux存储入门:简易数据恢复方案--分区和LVM实战

摘要:以黑箱方式完全依赖工具来进行数据恢复,所需时间和恢复的结果都难以估计。以专家或者专业方式进行数据恢复,技能和成本又太高。那么,数据恢复有没有较为合适的简易方案呢?我们以处理过的实际案例作答。

数据恢复有没有简易方案?

IT工程师一般都知道如何操作和使用文件和目录。但是,对于系统如何构建出、抽象出文件和目录,一般就不熟悉了。至于更下层的概念,可能大家知道最多的就是驱动了。所以,为了规避这点,可行的简易方案之一,就是以黑箱方式使用testdisk等工具,在我们在对底层了解不多甚至一无所知的情况下,进行数据恢复(商业工具,恢复效果估计更好,当然商业工具的价格也更好)。但是,对于工程师而言,多数时候,仅仅以黑箱方式依赖某些工具进行数据恢复是不够的。

数据恢复,经常是突发事故响应中关键而又耗时的一步。多数情况下,工程师往往并非专司数据恢复,操作环境往往是生产环境,趁手工具难以部署,执行操作要遵循种种约束,加之业务中断的压力。这种情形下,工程师很可能还需要推定数据恢复的结果/耗时等信息,提供数据供决策者使用。很明显,如果你准备考验一下自己的细致、耐心、知识和技能,数据恢复将是个不错的课题。当然,有一点是明确的,只是以黑箱方式使用testdisk等工具进行数据恢复,解决以上问题是不可能的。那么,有没有其他简易方案呢?

这里,我们以一个实际的case为例,讨论一下,在只使用UNIX常见工具(dd/grep/strace等)的情况下,如何简单、快捷的恢复数据。

预先准备

工具

我们要用到以下工具

工具功能示例

bc计算器echo 'ibase=2^3;i=0107000;ibase=2^3+2;i/512' | bc -l

dd检查或者拷贝磁盘/分区的内容,可以是几个扇区,也可以是几个字节dd if=/dev/sdb bs=1 count=64 skip=64 2>/dev/null | od -v -tx1

grep搜索制定字符串

od把二进制内容以ASCII或者16进制显示出来,搭配dd使用可以代替二进制编辑器dd if=/dev/sdb bs=1 count=64 skip=64 2>/dev/null | od -v -tx1

strace追踪应用的执行路径和对数据处理的流程strace ps

排查和诊断就是数据处理

如果对数据处理了解不多,请参考OSEMN

obtaining data/获取数据

crubbing data/清洗数据

exploring data/探索数据

modeling data/建模数据

interpreting data/解释数据

测试环境

使用Virtualbox,基于CentOS/Fedora/debian/Ubuntu搭建Linux实验环境。只需要学会strace工具和如下系统调用,就足以追踪系统如何处理诸如LVM物理卷元数据这样过的问题。

name功能

open打开一个文件,返回一个文件描述符供后续读写操作使用

dup/dup2复制文件描述符

lseek将读写指针移动到指定位置,后续操作从此指定位置读写

close关闭文件描述符

read读操作

数据恢复的原理和流程

什么是元数据

我们以大家都熟悉的磁盘作为存储设备的例子。

现代操作系统都会在磁盘上建立多个分层结构来管理和控制磁盘。比如,磁盘分区,分区上建立物理卷,物理卷上建立卷组,卷组上建立逻辑卷,逻辑卷上建立文件系统,就是这样的一个例子。如果你不熟悉LVM,请参考Logical Volume Manager

这些分层的结构都是很类似的。以磁盘分区为例。所谓分区,以大家最为熟悉的MBR: Master Boot Record结构为例。其实是第一个扇区记录了各个分区的起始扇区,大小和类型。系统需要时,比如启动过程中,系统只要从磁盘的第一个扇区读取这些数据即能拿到各个分区的数据。

具体看看分区的数据结构。以fdisk为例,分区的数据结构定义为

structdos_partition {unsignedcharboot_ind;/* 0x80 - active */unsignedcharbh, bs, bc;/* begin CHS */unsignedcharsys_ind;unsignedchareh, es, ec;/* end CHS */unsignedcharstart_sect[4];/* 分区开始扇区 */unsignedcharnr_sects[4];/* 分区包含的扇区数量 */} __attribute__((packed));

我们看看具体分区的例子,验证一下数据结构

分区使得磁盘上的扇区有了差别。第一个扇区(其实其编号是0),因分区数据记录其上而扮演特殊角色。明显,对系统而言,管理和操作分区实际上就是读写第一扇区上的对应记录而已。

类似分区信息这种系统用以管理某层资源的数据就是元数据

系统在磁盘上建立的各个分层结构,都有类似分区结构的数据结构。以LVM结构为例,我们可以把磁盘记录和LVM工具报告的数据做一对比。LVM数据的从第2个扇区开始,卷组数据在第8个扇区中,可以用dd命令提取相关扇区来验证LVM的数据结构。

下面是一份完整的LVM元数据信息,有兴趣者可以逐一清点各个对象。

[root@pusf ~]# pvdisplay;vgdisplay;lvdisplay--- Physical volume ---  PV Name              /dev/sda2  VG Name              cl  PV Size39.00GiB /notusable3.00MiB  AllocatableyesPE Size4.00MiB  Total PE9983Free PE1Allocated PE9982PV UUID              TIcs1T-Jksu-HKrn-fKqK-QF4K-ao1S-3PVBGI  --- Volume group ---  VG Name              cl  System ID  Format                lvm2  Metadata Areas1Metadata Sequence No5VG Access            read/write  VG Status            resizable  MAX LV0Cur LV2Open LV2Max PV0Cur PV1Act PV1VG Size39.00GiB  PE Size4.00MiB  Total PE9983Alloc PE / Size9982/38.99GiB  Free  PE / Size1/4.00MiB  VG UUID              KTVFwl-2QRE-ehf3-3dJb-bIfG-bpn0-8FnH7l  --- Logical volume ---  LV Path                /dev/cl/swap  LV Name                swap  VG Name                cl  LV UUID                Kc14dR-vFda-qdWJ-zUYo-lsDl-4oKq-RjjrBb  LV Write Access        read/write  LV Creation host, time localhost,2017-04-1813:23:08+0800LV Status              available# open                2LV Size2.00GiB  Current LE512Segments1Allocation            inherit  Read ahead sectors    auto  - currently setto8192Block device253:1--- Logical volume ---  LV Path                /dev/cl/root  LV Name                root  VG Name                cl  LV UUID                PWaI2g-t2Kq-h3aa-HgMC-cBp1-FjBp-dmaGeR  LV Write Access        read/write  LV Creation host, time localhost,2017-04-1813:23:09+0800LV Status              available# open                1LV Size36.99GiB  Current LE9470Segments1Allocation            inherit  Read ahead sectors    auto  - currently setto8192Block device253:0[root@pusf ~]# dd if=/dev/sda2 bs=512 count=16 skip=1 2>/dev/null | od -tc0000000L  A  B  E  L  O  N  E001\0\0\0\0\0\0\00000020270177251K\0\0\0L  V  M20010000040T  I  c  s1T  J  k  s  u  H  K  r  n  f  K0000060q  K  Q  F4K  a  o1S3P  V  B  G  I0000100\0\0360277\t\0\0\0\0\0020\0\0\0\0\00000120\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00000140\0\0\0\0\0\0\0\0\0020\0\0\0\0\0\00000160\0360017\0\0\0\0\0\0\0\0\0\0\0\0\00000200\0\0\0\0\0\0\0\0002\0\0\0001\0\0\00000220\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0*0007000252314344w      L  V  M2x  [5A  %  r00070200N  *  >001\0\0\0\0020\0\0\0\0\0\00007040\0360017\0\0\0\0\0\0026\0\0\0\0\0\00007060027005\0\0\0\0\0\0026G205374\0\0\0\00007100\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0*0010000c  l      {\ni  d      ="  K  T  V  F  w

0010020  l  -  2  Q  R  E  -  e  h  f  3  -  3  d  J  b

0010040  -  b  I  f  G  -  b  p  n  0  -  8  F  n  H  7

0010060  l  "\ns  e  q  n  o      =1\nf  o  r0010100m  a  t      ="  l  v  m  2  "\ns  t  a0010120t  u  s      =      ["  R  E  S  I  Z  E  A  B

0010140  L  E  ","  R  E  A  D  ","  W  R

0010160  I  T  E  "]\nf  l  a  g  s      =      [  ]0010200\ne  x  t  e  n  t  _  s  i  z  e      =80010220192\nm  a  x  _  l  v      =0\nm0010240a  x  _  p  v      =0\nm  e  t  a  d  a0010260t  a  _  c  o  p  i  e  s      =0\n\np0010300h  y  s  i  c  a  l  _  v  o  l  u  m  e  s0010320{\n\np  v0{\ni  d      ="  T

0010340  I  c  s  1  T  -  J  k  s  u  -  H  K  r  n  -

0010360  f  K  q  K  -  Q  F  4  K  -  a  o  1  S  -  3

0010400  P  V  B  G  I  "\nd  e  v  i  c  e      =0010420"  /  d  e  v  /  s  d  a  2  "\n\ns  t  a0010440t  u  s      =      ["  A  L  L  O  C  A  T  A

0010460  B  L  E  "]\nf  l  a  g  s      =      [  ]0010500\nd  e  v  _  s  i  z  e      =817800105206880\np  e  _  s  t  a  r  t      =00105402048\np  e  _  c  o  u  n  t      =00105609983\n}\n}\n\n\n}\n#      G0010600e  n  e  r  a  t  e  d      b  y      L  V  M20010620v  e  r  s  i  o  n2.02.1600106406(2)  -  R  H  E  L7(20160010660-09-28)  :      T  u  e      A  p  r00107001805:23:0820100107207\n\nc  o  n  t  e  n  t  s      ="  T

0010740  e  x  t      F  o  r  m  a  t      V  o  l  u  m

0010760  e      G  r  o  u  p  "\nv  e  r  s  i  o  n0011000=1\n\nd  e  s  c  r  i  p  t  i  o0011020n      ="  "\n\nc  r  e  a  t  i  o  n0011040_  h  o  s  t      ="  l  o  c  a  l  h  o

0011060  s  t  "\t#      L  i  n  u  x      l  o  c  a0011100l  h  o  s  t3.10.0-5140011120.  e  l7.  x86_64#  1      S0011140M  P      T  u  e      N  o  v22160011160:42:41U  T  C20160011200x86_64\nc  r  e  a  t  i  o  n  _0011220t  i  m  e      =14924929800112408\t#      T  u  e      A  p  r      1  8      000112605:23:082017\n\n\0\00011300\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0*0012000c  l      {\ni  d      ="  K  T  V  F  w

0012020  l  -  2  Q  R  E  -  e  h  f  3  -  3  d  J  b

0012040  -  b  I  f  G  -  b  p  n  0  -  8  F  n  H  7

0012060  l  "\ns  e  q  n  o      =2\nf  o  r0012100m  a  t      ="  l  v  m  2  "\ns  t  a0012120t  u  s      =      ["  R  E  S  I  Z  E  A  B

0012140  L  E  ","  R  E  A  D  ","  W  R

0012160  I  T  E  "]\nf  l  a  g  s      =      [  ]0012200\ne  x  t  e  n  t  _  s  i  z  e      =80012220192\nm  a  x  _  l  v      =0\nm0012240a  x  _  p  v      =0\nm  e  t  a  d  a0012260t  a  _  c  o  p  i  e  s      =0\n\np0012300h  y  s  i  c  a  l  _  v  o  l  u  m  e  s0012320{\n\np  v0{\ni  d      ="  T

0012340  I  c  s  1  T  -  J  k  s  u  -  H  K  r  n  -

0012360  f  K  q  K  -  Q  F  4  K  -  a  o  1  S  -  3

0012400  P  V  B  G  I  "\nd  e  v  i  c  e      =0012420"  /  d  e  v  /  s  d  a  2  "\n\ns  t  a0012440t  u  s      =      ["  A  L  L  O  C  A  T  A

0012460  B  L  E  "]\nf  l  a  g  s      =      [  ]0012500\nd  e  v  _  s  i  z  e      =817800125206880\np  e  _  s  t  a  r  t      =00125402048\np  e  _  c  o  u  n  t      =00125609983\n}\n}\n\nl  o  g  i  c  a0012600l  _  v  o  l  u  m  e  s      {\n\ns  w  a0012620p      {\ni  d      ="  K  c  1  4  d  R

0012640  -  v  F  d  a  -  q  d  W  J  -  z  U  Y  o  -

0012660  l  s  D  l  -  4  o  K  q  -  R  j  j  r  B  b

0012700  "\ns  t  a  t  u  s      =      ["  R  E  A

0012720  D  ","  W  R  I  T  E  ","  V  I

0012740  S  I  B  L  E  "]\nf  l  a  g  s      =0012760[  ]\nc  r  e  a  t  i  o  n  _  t  i  m  e0013000=1492492988\nc  r0013020e  a  t  i  o  n  _  h  o  s  t      ="  l

0013040  o  c  a  l  h  o  s  t  "\ns  e  g  m  e  n0013060t  _  c  o  u  n  t      =1\n\ns  e  g0013100m  e  n  t1{\ns  t  a  r  t  _  e  x0013120t  e  n  t      =0\ne  x  t  e  n  t  _0013140c  o  u  n  t      =512\n\nt  y  p0013160e      ="  s  t  r  i  p  e  d  "\ns  t0013200r  i  p  e  _  c  o  u  n  t      =1\n\n0013220s  t  r  i  p  e  s      =      [\n"  p  v  0

0013240  ",0\n]\n}\n}\n}\n\n}\n0013260#      G  e  n  e  r  a  t  e  d      b  y      L0013300V  M2v  e  r  s  i  o  n2.020013320.166(2)  -  R  H  E  L7(20013340016-09-28)  :      T  u  e0013360A  p  r1805:23:0800134002017\n\nc  o  n  t  e  n  t  s      =0013420"  T  e  x  t      F  o  r  m  a  t      V  o

0013440  l  u  m  e      G  r  o  u  p  "\nv  e  r  s0013460i  o  n      =1\n\nd  e  s  c  r  i  p0013500t  i  o  n      ="  "\n\nc  r  e  a  t0013520i  o  n  _  h  o  s  t      ="  l  o  c  a

0013540  l  h  o  s  t  "\t#      L  i  n  u  x      l0013560o  c  a  l  h  o  s  t3.10.0-0013600514.  e  l7.  x86_64#00136201S  M  P      T  u  e      N  o  v22001364016:42:41U  T  C20001366016x86_64\nc  r  e  a  t  i0013700o  n  _  t  i  m  e      =14924900137202988\t#      T  u  e      A  p  r      10013740805:23:082017\n0013760\n\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00014000c  l      {\ni  d      ="  K  T  V  F  w

0014020  l  -  2  Q  R  E  -  e  h  f  3  -  3  d  J  b

0014040  -  b  I  f  G  -  b  p  n  0  -  8  F  n  H  7

0014060  l  "\ns  e  q  n  o      =3\nf  o  r0014100m  a  t      ="  l  v  m  2  "\ns  t  a0014120t  u  s      =      ["  R  E  S  I  Z  E  A  B

0014140  L  E  ","  R  E  A  D  ","  W  R

0014160  I  T  E  "]\nf  l  a  g  s      =      [  ]0014200\ne  x  t  e  n  t  _  s  i  z  e      =80014220192\nm  a  x  _  l  v      =0\nm0014240a  x  _  p  v      =0\nm  e  t  a  d  a0014260t  a  _  c  o  p  i  e  s      =0\n\np0014300h  y  s  i  c  a  l  _  v  o  l  u  m  e  s0014320{\n\np  v0{\ni  d      ="  T

0014340  I  c  s  1  T  -  J  k  s  u  -  H  K  r  n  -

0014360  f  K  q  K  -  Q  F  4  K  -  a  o  1  S  -  3

0014400  P  V  B  G  I  "\nd  e  v  i  c  e      =0014420"  /  d  e  v  /  s  d  a  2  "\n\ns  t  a0014440t  u  s      =      ["  A  L  L  O  C  A  T  A

0014460  B  L  E  "]\nf  l  a  g  s      =      [  ]0014500\nd  e  v  _  s  i  z  e      =817800145206880\np  e  _  s  t  a  r  t      =00145402048\np  e  _  c  o  u  n  t      =00145609983\n}\n}\n\nl  o  g  i  c  a0014600l  _  v  o  l  u  m  e  s      {\n\ns  w  a0014620p      {\ni  d      ="  K  c  1  4  d  R

0014640  -  v  F  d  a  -  q  d  W  J  -  z  U  Y  o  -

0014660  l  s  D  l  -  4  o  K  q  -  R  j  j  r  B  b

0014700  "\ns  t  a  t  u  s      =      ["  R  E  A

0014720  D  ","  W  R  I  T  E  ","  V  I

0014740  S  I  B  L  E  "]\nf  l  a  g  s      =0014760[  ]\nc  r  e  a  t  i  o  n  _  t  i  m  e0015000=1492492988\nc  r0015020e  a  t  i  o  n  _  h  o  s  t      ="  l

0015040  o  c  a  l  h  o  s  t  "\ns  e  g  m  e  n0015060t  _  c  o  u  n  t      =1\n\ns  e  g0015100m  e  n  t1{\ns  t  a  r  t  _  e  x0015120t  e  n  t      =0\ne  x  t  e  n  t  _0015140c  o  u  n  t      =512\n\nt  y  p0015160e      ="  s  t  r  i  p  e  d  "\ns  t0015200r  i  p  e  _  c  o  u  n  t      =1\n\n0015220s  t  r  i  p  e  s      =      [\n"  p  v  0

0015240  ",0\n]\n}\n}\n\nr  o  o  t0015260{\ni  d      ="  P  W  a  I  2  g  -

0015300  t  2  K  q  -  h  3  a  a  -  H  g  M  C  -  c

0015320  B  p  1  -  F  j  B  p  -  d  m  a  G  e  R  "0015340\ns  t  a  t  u  s      =      ["  R  E  A  D

0015360  ","  W  R  I  T  E  ","  V  I  S

0015400  I  B  L  E  "]\nf  l  a  g  s      =      [0015420]\nc  r  e  a  t  i  o  n  _  t  i  m  e0015440=1492492989\nc  r  e0015460a  t  i  o  n  _  h  o  s  t      ="  l  o

0015500  c  a  l  h  o  s  t  "\ns  e  g  m  e  n  t0015520_  c  o  u  n  t      =1\n\ns  e  g  m0015540e  n  t1{\ns  t  a  r  t  _  e  x  t0015560e  n  t      =0\ne  x  t  e  n  t  _  c0015600o  u  n  t      =9470\n\nt  y  p0015620e      ="  s  t  r  i  p  e  d  "\ns  t0015640r  i  p  e  _  c  o  u  n  t      =1\n\n0015660s  t  r  i  p  e  s      =      [\n"  p  v  0

0015700  ",512\n]\n}\n}\n}\n\n0015720}\n#      G  e  n  e  r  a  t  e  d      b  y0015740L  V  M2v  e  r  s  i  o  n2.001576002.166(2)  -  R  H  E  L70016000(2016-09-28)  :      T  u0016020e      A  p  r1805:23:0001604092017\n\nc  o  n  t  e  n  t  s0016060="  T  e  x  t      F  o  r  m  a  t

0016100  V  o  l  u  m  e      G  r  o  u  p  "\nv  e0016120r  s  i  o  n      =1\n\nd  e  s  c  r0016140i  p  t  i  o  n      ="  "\n\nc  r  e0016160a  t  i  o  n  _  h  o  s  t      ="  l  o

0016200  c  a  l  h  o  s  t  "\t#      L  i  n  u  x0016220l  o  c  a  l  h  o  s  t3.10.00162400-514.  e  l7.  x86_640016260#  1      S  M  P      T  u  e      N  o  v00163002216:42:41U  T  C00163202016x86_64\nc  r  e  a0016340t  i  o  n  _  t  i  m  e      =14920016360492989\t#      T  u  e      A  p  r00164001805:23:0920100164207\n\n\0\0\0\0\0\0\0\0\0\0\0\0\00016440\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0*0017000c  l      {\ni  d      ="  K  T  V  F  w

0017020  l  -  2  Q  R  E  -  e  h  f  3  -  3  d  J  b

0017040  -  b  I  f  G  -  b  p  n  0  -  8  F  n  H  7

0017060  l  "\ns  e  q  n  o      =4\nf  o  r0017100m  a  t      ="  l  v  m  2  "\ns  t  a0017120t  u  s      =      ["  R  E  S  I  Z  E  A  B

0017140  L  E  ","  R  E  A  D  ","  W  R

0017160  I  T  E  "]\nf  l  a  g  s      =      [  ]0017200\ne  x  t  e  n  t  _  s  i  z  e      =80017220192\nm  a  x  _  l  v      =0\nm0017240a  x  _  p  v      =0\nm  e  t  a  d  a0017260t  a  _  c  o  p  i  e  s      =0\n\np0017300h  y  s  i  c  a  l  _  v  o  l  u  m  e  s0017320{\n\np  v0{\ni  d      ="  T

0017340  I  c  s  1  T  -  J  k  s  u  -  H  K  r  n  -

0017360  f  K  q  K  -  Q  F  4  K  -  a  o  1  S  -  3

0017400  P  V  B  G  I  "\nd  e  v  i  c  e      =0017420"  /  d  e  v  /  s  d  a  2  "\n\ns  t  a0017440t  u  s      =      ["  A  L  L  O  C  A  T  A

0017460  B  L  E  "]\nf  l  a  g  s      =      [  ]0017500\nd  e  v  _  s  i  z  e      =817800175206880\np  e  _  s  t  a  r  t      =00175402048\np  e  _  c  o  u  n  t      =00175609983\n}\n\np  v1{\ni  d0017600="  R  c  p  o  7  Z  -  Q  I  e  g  -

0017620  F  G  V  D  -  T  S  Z  I  -  s  o  Q  O  -  I

0017640  g  a  T  -  r  Q  w  D  4  Y  "\nd  e  v  i0017660c  e      ="  /  d  e  v  /  s  d  b  6  "0017700\n\ns  t  a  t  u  s      =      ["  A  L  L

0017720  O  C  A  T  A  B  L  E  "]\nf  l  a  g  s0017740=      [  ]\nd  e  v  _  s  i  z  e      =0017760409601\np  e  _  s  t  a  r  t0020000[root@pusf ~]#

元数据和数据:数据损坏分类

系统把磁盘的扇区分成两种来支持分区:第一扇区和所有其他非第一扇区。并且在第一个扇区上记录分区信息,即元数据。而其他非第一扇区则供分区层使用,从磁盘的视角看,其他非第一扇区则是数据部分。我们逐层考察下磁盘、分区和LVM结构

系统启动时,会逐层读取各层元数据,创建各层数据结构。如果某一层元数据损坏或者丢失,那么系统就没有办法完成创建各层数据结构的任务。这种情况下,从客户角度看,很可能就是数据损坏了。比如,如果你把第一个扇区用\0覆盖一遍,那么系统就识别不到分区内容了。当然这种情况下分区层以上的内容,比如物理卷信息,系统也无法处理了。因此,对于数据恢复任务而言,如果元数据损坏,则修复元数据总是必须的,而且往往是第一步。

当然,如果数据损坏了,即使元数据完好无缺,那么数据也是损坏了。比如,你误删了一个文件,那么,分区结构再完好对于文件被删也于事无补。

基于以上分析,我们可以把数据损坏简单分三类类:元数据损坏、数据损坏或者前面两种损坏类型的混合型损坏。

元数据修复可以简易处理

以基于磁盘的分区、LVM以及文件系统为例。分层结构的数据格式都有严格的格式(比如分区的数据结构就是一个C的struct),出现位置也固定(有关分区的元数据记录在第一个扇区的446~462字节之间),而且这些数据结构往往都带有魔数(比如,分区的类型83),而且常用的分层结构,也不外乎分区、LVM以及文件系统等几种。因此,对于元数据以及系统如何处理元数据,我们都容易追踪和检查。因此,可以预期,修复元数据,有简易方案。

原理

如果有数据损坏,那么除非有日志、备份,或者数据本身有逻辑可供使用,否则数据是不能恢复了。比如,通常的文件删除操作,系统只是解除了文件名称和文件内容相关间的联系而已。文件本身的内容还是记录再磁盘上。这种情况下,只要重建文件名称和文件内容间的联系即可恢复文件。

相对而言,简单情形的是元数据损坏。如果只是元数据损坏,而且我们知道正确的元数据。因为元数据操作,不会触及数据部分,因此,我们只要重建元数据部分即可恢复数据。如果涉及到多层,则逐层恢复即可。以分区丢失为例。

比如我们有一块数据盘,整盘我们只是用fdisk分了一个区,现在分区丢失了。这种情形下,只要用fdsik,按照默认情形,重新分区就能恢复分区。

就这种情形,我们给出一个可用的分析流程。

症状和初步排查

症状

客户反馈

降配重启后,系统无法启动

排查发现客户一逻辑卷无法挂载导致重启失败。在/etc/fstab中注释掉逻辑卷的挂载配置,系统启动成功。

但是客户的逻辑卷上有重要数据。此逻辑卷在数据盘上,数据盘大小是2TB。此磁盘全部2TB全部分配给一个分区,此分区上创建有LVM结构。

分区数据如下

[root@localhost ~]# fdisk -l -u /dev/vdbDisk /dev/vdb: 2199.0 GB,2199023255552bytes5 heads,3sectors/track,286331153cylinders, total4294967296sectorsUnits = sectors of1*512=512bytesSector size (logical/physical):512bytes /512bytesI/O size (minimum/optimal):512bytes /512bytesDisk identifier: 0xde220917  Device Boot      Start        End      Blocks  Id  System/dev/vdb1204842949672942147482623+83Linux[root@localhost ~]#

初步排查

首先确定分区上是否有数据,通过查看一些扇区,我们就会有很大的概率确认这一点。当然也可以逐扇区确认。

逐扇区确认,可以用如下命令办理。假设磁盘是/dev/vdb。

max_sector_to_check=nrsectorforiin$(seq0${max_sector_to_check});doddif=/dev/vdbbs=512count=1skip=${i}2>/dev/null| sha256sum;done |sort -n| uniq;

当然,也可以通过抽样检查来确认。这种方法通常是检查磁盘分区的前面一部分扇区。比如,下面的例子,通过检查前面几十个扇区,我们可以确认磁盘上确有数据。

[root@localhost ~]# dd if=/dev/vdb1 bs=512count=602>/dev/null | od -tx1000000000000000000000000000000000000000*0007000f9800000f9800100f9800200f98003000007020f9800400f9800c00f9800d00f98018000007040f9802800f9803e00f9807900f980ab000007060f9803801f9806c01f9804504f980b0040007100f9801a06f980d00c f980841e00000000000712000000000000000000000000000000000*0017000fa800000fa800100fa800200fa8003000017020fa800400fa800c00fa800d00fa8018000017040fa802800fa803e00fa807900fa80ab000017060fa803801fa806c01fa804504fa80b0040017100fa801a06fa80d00c fa80841e00000000001712000000000000000000000000000000000*0027000fb800000fb800100fb800200fb8003000027020fb800400fb800c00fb800d00fb8018000027040fb802800fb803e00fb807900fb80ab000027060fb803801fb806c01fb804504fb80b0040027100fb801a06fb80d00c fb80841e00000000002712000000000000000000000000000000000*0037000fc800000fc800100fc800200fc8003000037020fc800400fc800c00fc800d00fc8018000037040fc802800fc803e00fc807900fc80ab000037060fc803801fc806c01fc804504fc80b0040037100fc801a06fc80d00c fc80841e00000000003712000000000000000000000000000000000*0047000fd800000fd800100fd800200fd8003000047020fd800400fd800c00fd800d00fd8018000047040fd802800fd803e00fd807900fd80ab000047060fd803801fd806c01fd804504fd80b0040047100fd801a06fd80d00c fd80841e00000000004712000000000000000000000000000000000*0057000fe800000fe800100fe800200fe8003000057020fe800400fe800c00fe800d00fe8018000057040fe802800fe803e00fe807900fe80ab000057060fe803801fe806c01fe804504fe80b0040057100fe801a06fe80d00c fe80841e00000000005712000000000000000000000000000000000*0067000ff800000ff800100ff800200ff8003000067020ff800400ff800c00ff800d00ff8018000067040ff802800ff803e00ff807900ff80ab000067060ff803801ff806c01ff804504ff80b0040067100ff801a06ff80d00c ff80841e00000000006712000000000000000000000000000000000*0074000[root@localhost ~]#

接下来使用testdisk工具恢复数据。尝试数次,testdisk工具总是在扫描到2%时停滞,处理过程不能继续。

初次恢复尝试

分区还在,但是LVM结构丢失,经检查,由LVM工具链维护的备份数据/etc/lvm/backup/vg_xxxxxx文件还在。因此,这种情形下,按照我们的恢复流程,只要在分区之上,尝试重建LVM和文件系统,应该就可以解决问题。

[root@localhost~]# pvdisplay /dev/vdbFailedtofind deviceforphysical volume"/dev/vdb".[root@localhost~]# ls /etc/lvm/backup/vg_xxxxxx/etc/lvm/backup/vg_xxxxxx[root@localhost~]#

根据备份数据恢复LVM结构,可以参考Recovering Physical Volume Metadata。可惜的是,我们第一步就折戟沉沙了。

[root@localhost ~]# pvcreate --uuid "X1cHlO-kdFk-RZIM-1L12-qHit-0QA5-C1fZxm" --restorefile /etc/lvm/backup/vg_xxxxxx /dev/vdb1WARNING: Device /dev/vdb1 has sizeof4294965247sectors whichissmaller than corresponding PV sizeof4294966977sectors. Was device resized?  Oneormore devices usedasPVsinVG vg_xxxxxx have changed sizes.  Can't initialize physical volume"/dev/vdb1"ofvolume group"vg_xxxxxx"without-ff[root@localhost ~]#

看样子,分区的数据有些地方出错了。根据上面命令报错的信息,对比LVM的备份数据和分区数据,很快我们就发现了问题。现有分区记录的其拥有的扇区数目,少于其上LVM卷组记录的扇区数量。

问题出在哪里?

因为种种原因,我们不能确认分区信息和LVM备份数据为何不一致。但是,我们可以进一步从磁盘上提取、分析数据。因为有关分区的元数据在(分区在),所以我们进一步检查磁盘上还有没有有关LVM的元数据?这只要使用下面的命令行

ddif=/dev/vdb1 bs=512count=1282>/dev/null| od -tc

结果及其结果分析如下

所以,磁盘上还有有关LVM的元数据,但是为什么系统没有凭借这些数据构建出LVM结构呢?我们创建一个测试环境,用strace追踪下系统处理LVM物理卷元数据的执行路径。如下命令即可

strace-s512pvdisplay

当然,更好的办法是把strace记录放置到文件中,以备仔细检查

starce -o path_to_strace_log-s512-f-ff pvdisplay

我们组合使用strace和grep命令来确认系统默认的LVM物理卷位置。如果你没有耐心分析下面的数据,请跳过直接看后面的截图

strace -o /tmp/pvdisplay-strace.log-s512pvdisplaygrep -E'^open|^lseek|^read'/tmp/pvdisplay-strace.log

数据清洗结果如下。如果没有耐心分析,请跳过直接看下面的分析截图

[root@localhost ~]# grep -E '^open|^lseek|^read|^close' /tmp/pvdisplay-strace.log…close(4)                                =0open("/dev/vdb1", O_RDONLY|O_DIRECT|O_NOATIME) =4close(4)                                =0open("/dev/vdb1", O_RDONLY|O_DIRECT|O_NOATIME) =4lseek(4,21037056, SEEK_SET)            =21037056read(4,"…",512) =512lseek(4,21118976, SEEK_SET)            =21118976read(4,"…",512) =512lseek(4,0, SEEK_SET)                  =0read(4,"…",512) =512lseek(4,4096, SEEK_SET)                =4096read(4,"\26\326\216\333 LVM2 x[5A%r0N*>\1\0\0…",512) =512close(4)                                =0…[root@localhost ~]#

很明显,系统预期LVM元数据是在分区的第8个扇区,但是在需要做数据恢复的磁盘上,LVM的元数据却是在第71个扇区,而分区的起始扇区是2048,因此,LVM数据根本不在分区内。这就是为什么磁盘上还有LVM元数据,系统却没有识别出来LVM的原因。

既然系统是因为有关LVM的元数据所在扇区不对而导致系统无法识别LVM结构,设想通过重新分区,我们把有关LVM元数据调整到分区的第8个扇区。稍加计算,就会发现,只要把分区的起始扇区从第2048个扇区调整到第63个扇区即可。不仅如此,通过调整分区大小,我们同样也解决了磁盘分区扇区数不足的问题

数据恢复

较新的fdisk工具,不允许起始扇区小于2048,因此,我们用parted工具来调整分区的起始扇区。

调整过程是先删掉扇区,而后再创建之。而结果正如我们所预期的,分区调整完成,客户的数据立刻恢复了。物理卷、卷组、逻辑卷、文件系统以及数据,都完好无损。

结语

从处理这个实际case可以看出,如果知道如何识别各层元数据,比如分区LVM文件系统;能够追踪系统处理各层元数据的逻辑,那么,组合使用UNIX常用的ddod等工具,足以简单有效的处理元数据损坏的情形,快速恢复数据。如果掌握了常见的系统调用,并且掌握了strace工具,那么对于如何识别元数据以及系统如何处理元数据,完全可以通过简单分析strace输出拿到相应答案。

除了易学、简单、快捷、高效,元数据修复方案还有一个优点,就是可以确保不会破坏数据。这可能是这个方案的最大亮点。

参考

本文提供链接,优先链接内容的严谨与可靠性,而非便利性。如链接无法访问,请按照文字自行检索资料和图书。

1.数据恢复软件列表

2.shred (Unix)

3.使用Linux文件恢复工具

4.如何恢复 Linux 上删除的文件,第 1 部分

5.硬盘分区

6.RHEL 6 Logical Volume Manager Administration

7.Linux 文件系统剖析

8.Linux man pages online

9.元数据

10.Linux文件系统中元数据的加锁机制与组织方式

本文为云栖社区原创内容,未经允许不得转载,如需转载请发送邮件至yqeditor@list.alibaba-inc.com;如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:yqgroup@service.aliyun.com 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。

原文链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容