linux操作系統故障處理-ext4文件系統超級塊損壞修復


背景

      前天外面出差大數據測試環境平台有7台服務器掛了,同事重啟好了五台服務器,但是還有兩台服務器啟動不起來,第二天回來后我和同事再次去機房檢查,發現兩台服務器都顯示superblock的報錯,經過一番處理后兩台服務器都正常進系統了,現決定重現superblock故障並將此類問題故障處理思路寫下來方便后面新同事參考。

硬盤的結構

硬盤的物理結構側視圖和俯視圖,這兩張圖傳遞出來的比較重要的信息如下:

磁盤划分為磁頭(Head),柱面(Cylinder),扇區(Sector)

磁頭:每個磁片正反兩面各有一個磁頭,磁頭固定在可移動的機械臂上,用於讀寫數據

磁道:當硬盤盤片旋轉時,磁頭若保持在一個位置上,則磁頭會在盤片表面划出一個圓形軌跡,這些圓形軌跡就叫做磁道,磁道由外向內從0開始編號。

柱面:磁片中半徑相同的同心磁道(Track)構成柱面。在實際應用中經常用到的磁盤分區就是用它作為范圍划分的(重要)。

扇區:每個磁道上的一個弧段被成為一個扇區,它是硬盤的最小組成單元,一般扇區的大小是512字節。

了解了這幾個概念就能算出一個分區的大小

硬盤容量:磁頭數*柱面數*扇區數*512

磁盤sda的容量是: 255 * 2610 * 63 * 512 = 21467980800 ,算出的容量跟系統顯示的基本一致。

[root@server1 ~]# fdisk -l Disk /dev/sda: 21.5 GB, 21474836480 bytes 255 heads, 63 sectors/track, 2610 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x000205e3 Device Boot Start End Blocks Id System /dev/sda1   *           1          26      204800   83 Linux Partition 1 does not end on cylinder boundary. /dev/sda2              26        2611    20765696 8e Linux LVM Disk /dev/sdb: 10.7 GB, 10737418240 bytes 255 heads, 63 sectors/track, 1305 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000

ext4文件系統

由於Linux系統是多用戶多的。從ext2開始,將磁盤分區格式化后是將文件屬性和文件內容分開存儲的,分別由inode和block來負責。

inode


    用於存儲文件的各屬性,包括:



     - 所有者信息:文件的owner,group;



     - 權限信息:read、write和excite;



     -時間信息:建立或改變時間(ctime)、最后讀取時間(atime)、最后修改時間(mtime);



     - 標志信息:一些flags;



     - 內容信息:type,size,以及相應的block的位置信息。



    注意:不記錄文件名或目錄名,文件名或目錄名記錄在文件所在目錄對應的block里。

   inode的大小一般是12Bytes,也可能是256 Bytes.


block


     用於存儲文件的內容,它的大小一般是1K,2K,4K,一般在磁盤格式化的時候就默認了。


因為現在的磁盤都比較大,對其進行格式化后inode和block的個數將會非常大,為了便於管理,ext4文件系統在格式化的時候基本上是區分為多個區塊群組(block group),這個跟軍隊里層級划分很像哦.
ext4文件系統格式化后的划分是下面這樣的。


ext2文件系統示意圖

Boot Sector 是用於引導分區上的操作系統的,這個一般用在雙系統上,這里就直接忽略了。

Block Group 為了便於管理,文件系統格式化的時候划分為了多個區塊群組,它里面保存了以下內容:

超級塊(Superblock):

  Superblock 是記錄整個 filesystem 相關信息的地方.為了系統的健壯性,最初每個塊組都有超級塊和組描述符表的一個拷貝,但是當文件系統很大時,這樣浪費了很多塊(尤其是組描述符表占用的塊多),后來采用了一種稀疏的方式來存儲這些拷貝,只有塊組號是3, 5 ,7的冪的塊組(譬如說1,3,5,7,9,25,49…)才備份這個拷貝。通常情況下,只有主拷貝(第0塊塊組)的超級塊信息被文件系統使用,其它拷貝只有在主拷貝被破壞的情況下才使用,他記錄的信息主要有:

block 與 inode 的總量;

  • 未使用與已使用的 inode / block 數量;
  • block 與 inode 的大小 (block 為 1, 2, 4K,inode 為 128 ,256bytes);
  • filesystem 的掛載時間、最近一次寫入數據的時間、最近一次檢驗磁盤 (fsck) 的時間等文件系統的相關信息;
  • 一個 valid bit 數值,若此文件系統已被掛載,則 valid bit 為 0 ,若未被掛載,則 valid bit 為 1 。
  • 檔案系統描述(Filesystem Description):

        這個區段可以描述每個 block group 的開始與結束的 block 號碼,以及說明每個區段 (superblock, bitmap, inodemap, data block) 分別介於哪一個 block 號碼之間.

    區塊位圖(block bitmap)

        區塊對應表用於描述該塊組所管理的塊的分配狀態。如果某個塊對應的位未置位,那么代表該塊未分配,可以用於存儲數據;否則,代表該塊已經用於存儲數據或者該塊不能夠使用(譬如該塊物理上不存在)。由於區塊位圖僅占一個塊,因此這也就決定了塊組的大小。

    Inode位圖(Inode bitmap)

        Inode位圖用於描述該塊組所管理的inode的分配狀態。我們知道inode是用於描述文件的元數據,每個inode對應文件系統中唯一的一個號,如果inode位圖中相應位置位,那么代表該inode已經分配出去;否則可以使用。由於其僅占用一個塊,因此這也限制了一個塊組中所能夠使用的最大inode數量。

    Inode table(Inode表)

        Inode表用於存儲inode信息。它占用一個或多個塊(為了有效的利用空間,多個inode存儲在一個塊中),其大小取決於文件系統創建時的參數,由於inode位圖的限制,決定了其最大所占用的空間。

    Data block(數據塊)

        數據塊存放真正的文件數據


    模擬文件系統故障和故障處理解決

    模擬superblock超級塊故障

    現在回過頭來觀察自己的文件系統,每個區段與superblock的信息都可以使用dumpe2fs這個命令來查詢

    [root@server1 ~]# dumpe2fs /dev/sdb|more dumpe2fs 1.41.12 (17-May-2010) Filesystem volume name: <none>           ---------->> 文件系統的名稱 Last mounted on: <not available>           -------------------------------->> 分區掛載,當前沒有掛載,所以顯示不可用 Filesystem UUID: c6421bf7-8497-45c0-86b0-dfac1b21989a Filesystem magic number: 0xEF53 Filesystem revision #: 1 (dynamic) Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize ----------->> 文件系統的一些特性 Filesystem flags: signed_directory_hash Default mount options: (none) Filesystem state: clean ----------->> 文件系統當前是好的(clean) Errors behavior: Continue Filesystem OS type: Linux Inode count: 655360               -------->> Inode 總的個數 Block count: 2621440           --------->> Block 總的個數 Reserved block count: 131072 Free blocks: 2541777     --------->> 空閑的block個數 Free inodes: 655349  ----------->> 空閑的inode個數 First block: 0                 ------------->>第一個block的編號 Block size: 4096            --------------->> block的大小,這里是4K Fragment size: 4096 Reserved GDT blocks: 639 Blocks per group: 32768            ------------------->> 每個塊組block的個數 Fragments per group: 32768 Inodes per group: 8192             ------------>> 每個塊組inode的個數 Inode blocks per group: 512 Flex block group size: 16 Filesystem created: Sat Nov 11 13:23:30 2017 Last mount time:          n/a Last write time:          Sat Nov 11 13:23:32 2017 Mount count: 0 Maximum mount count:      33 Last checked: Sat Nov 11 13:23:30 2017 Check interval: 15552000 (6 months) Next check after: Thu May 10 13:23:30 2018 Lifetime writes: 291 MB Reserved blocks uid: 0 (user root) Reserved blocks gid: 0 (group root) First inode: 11 Inode size: 256    ------------>> inode的大小 Required extra isize: 28 Desired extra isize: 28 Journal inode: 8 Default directory hash: half_md4 Directory Hash Seed: 2fd3813e-6245-4a62-bc28-34c1534c919d Journal backup: inode blocks Journal features: (none) 日志大小: 128M Journal length: 32768 Journal sequence: 0x00000001 Journal start: 0 Group 0: (Blocks 0-32767) [ITABLE_ZEROED] 校驗和 0xee7f,8181個未使用的inode 主 superblock at 0, Group descriptors at 1-1               -------------->> 主superblock的位置在編號為0的block中 保留的GDT塊位於 2-640 Block bitmap at 641 (+641), Inode bitmap at 657 (+657) Inode表位於 673-1184 (+673) 23897 free blocks, 8181 free inodes, 2 directories, 8181個未使用的inodes 可用塊數: 8871-32767 可用inode數: 12-8192 Group 1: (Blocks 32768-65535) [INODE_UNINIT, ITABLE_ZEROED] 校驗和 0x1ae3,8192個未使用的inode 備份 superblock at 32768, Group descriptors at 32769-32769   ------------->>  備份superblock的位置在編號為 32768 的block中 保留的GDT塊位於 32770-33408 Block bitmap at 642 (+4294935170), Inode bitmap at 658 (+4294935186) Inode表位於 1185-1696 (+4294935713) 32127 free blocks, 8192 free inodes, 0 directories, 8192個未使用的inodes 可用塊數: 33409-65535 可用inode數: 8193-16384 Group 2: (Blocks 65536-98303) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED] 校驗和 0x8b39,8192個未使用的inode Block bitmap at 643 (+4294902403), Inode bitmap at 659 (+4294902419) Inode表位於 1697-2208 (+4294903457) 32768 free blocks, 8192 free inodes, 0 directories, 8192個未使用的inodes 可用塊數: 65536-98303 可用inode數: 16385-24576 Group 3: (Blocks 98304-131071) [INODE_UNINIT, ITABLE_ZEROED] 校驗和 0x6c3d,8192個未使用的inode 備份 superblock at 98304, Group descriptors at 98305-98305 保留的GDT塊位於 98306-98944 Block bitmap at 644 (+4294869636), Inode bitmap at 660 (+4294869652) Inode表位於 2209-2720 (+4294871201) 32127 free blocks, 8192 free inodes, 0 directories, 8192個未使用的inodes 可用塊數: 98945-131071 可用inode數: 24577-32768

    說到這里心里大概有譜了,原來superblock在文件系統上是有備份的,那我們模擬下主superblock出問題,看如何恢復

    這里直接利用dd命令將sdb磁盤第一個block的內容抹除

    [root@server1 ~]# dd if=/dev/zero of=/dev/sdb bs=1 count=4096 記錄了4096+0 的讀入 記錄了4096+0 的寫出 4096字節(4.1 kB)已復制,0.019493 秒,210 kB/秒 [root@server1 ~]# dumpe2fs /dev/sdb dumpe2fs 1.41.12 (17-May-2010) dumpe2fs: Bad magic number in super-block 當嘗試打開 /dev/sdb 時 找不到有效的文件系統超級塊. [root@server1 ~]# tune2fs -l /dev/sdb tune2fs 1.41.12 (17-May-2010) tune2fs: Bad magic number in super-block 當嘗試打開 /dev/sdb 時 找不到有效的文件系統超級塊. [root@server1 ~]#

    這時候我們根本無法從dumpe2fs和tune2fs看到Backup superblock的位置,都找不到superblock備份的位置該怎么恢復主superblock呢

    注意下面的命令都是針對ext類文件系統的,其它文件系統不適用

    首先要找到superblock備份的幾個位置,這需要利用mke2fs這個命令

    mke2fs:create an ext2/ext3/ext4 filesystem

    利用mke2fs這個命令 mke2fs  -n  設備名,為了不引起歧義,所以這里直接復制了原文解釋。

    -n     Causes mke2fs to not actually create a filesystem, but display what it would do if it were to create
                   a filesystem.  This can be used to determine the location of the backup superblocks for a particular
                   filesystem,  so  long  as  the mke2fs parameters that were passed when the filesystem was originally
                   created are used again.  (With the -n option added, of course!)

    簡單來說就是接了-n 參數 ,mke2fs 不是真的在設備上創建文件系統,它只是模擬這個過程並顯示給你看。讓你明白它究竟做了那些事。

    [root@server1 ~]# mke2fs -n /dev/sdb mke2fs 1.41.12 (17-May-2010) /dev/sdb is entire device, not just one partition! 無論如何也要繼續? (y,n) y 文件系統標簽= 操作系統:Linux 塊大小=4096 (log=2) 分塊大小=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 655360 inodes, 2621440 blocks 131072 blocks (5.00%) reserved for the super user 第一個數據塊=0 Maximum filesystem blocks=2684354560
    80 block groups
    32768 blocks per group, 32768 fragments per group 8192 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632  --------------->>> 超級塊的備份位置就在這里 [root@server1 ~]#

    利用上面的命令就可以找到超級塊的備份位置了。然后我們就可以再利用系統提供的另一個磁盤命令e2fsck命令進行恢復,它有一個-b選項,由於我的操作系統是ext4格式的,也可以用fsck.ext4 -b 32768 /dev/sdb,效果一樣。

    恢復的命令格式:  e2fsck –b superblock   device

    -b superblock
                   Instead of using the normal superblock, use an alternative superblock specified by superblock.  This
                   option is normally used when the primary superblock has been corrupted.  The location of the  backup
                   superblock is dependent on the filesystem’s blocksize.  For filesystems with 1k blocksizes, a backup
                   superblock can be found at block 8193; for filesystems with 2k blocksizes, at block 16384;  and  for
                   4k blocksizes, at block 32768.

                  Additional  backup  superblocks can be determined by using the mke2fs program using the -n option to
                   print out where the superblocks were created.   The -b option to mke2fs, which  specifies  blocksize
                   of the filesystem must be specified in order for the superblock locations that are printed out to be
                   accurate.

                  If an alternative superblock is specified and the filesystem is not opened  read-only,  e2fsck  will
                   make  sure  that  the  primary superblock is updated appropriately upon completion of the filesystem
                   check.

    [root@server1 ~]# e2fsck -b 32768 /dev/sdb e2fsck 1.41.12 (17-May-2010) /dev/sdb was not cleanly unmounted, 強制檢查. 第一步: 檢查inode,塊,和大小 第二步: 檢查目錄結構 第3步: 檢查目錄連接性 Pass 4: Checking reference counts 第5步: 檢查簇概要信息 /dev/sdb: ***** 文件系統已修改 *****
    /dev/sdb: 11/655360 files (0.0% non-contiguous), 79663/2621440 blocks [root@server1 ~]# dumpe2fs /dev/sdb|more dumpe2fs 1.41.12 (17-May-2010) Filesystem volume name: <none> Last mounted on: <not available> Filesystem UUID: c6421bf7-8497-45c0-86b0-dfac1b21989a Filesystem magic number: 0xEF53 Filesystem revision #: 1 (dynamic) Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize Filesystem flags: signed_directory_hash Default mount options: (none) Filesystem state: clean Errors behavior: Continue Filesystem OS type: Linux Inode count: 655360 Block count: 2621440 Reserved block count: 131072 Free blocks: 2541777 Free inodes: 655349 First block: 0 Block size: 4096 Fragment size: 4096 Reserved GDT blocks: 639 Blocks per group: 32768 Fragments per group: 32768 Inodes per group: 8192 Inode blocks per group: 512 Flex block group size: 16 Filesystem created: Sat Nov 11 13:23:30 2017 Last mount time:          n/a Last write time:          Sat Nov 11 16:57:39 2017 Mount count: 0 Maximum mount count:      33 Last checked: Sat Nov 11 16:57:39 2017

    現在主超級塊已經恢復了,系統可以正常使用。

    模擬組描述錯誤故障和解決故障

    那如果檔案系統描述(GDT)損壞了怎么辦,這里也可以試驗下:

    這里塊組1的組描述符是在第二個塊的,直接利用dd覆蓋第二個塊,可以看到現在磁盤已經無法進行掛載了。並且系統提示組塊0有錯誤。

    [root@server1 /]# dd if=/dev/zero of=/dev/sdb bs=1 count=4096 seek=4096 記錄了4096+0 的讀入 記錄了4096+0 的寫出 4096字節(4.1 kB)已復制,0.0795117 秒,51.5 kB/秒 [root@server1 /]# mount /dev/sdb /data/
    mount: wrong fs type, bad option, bad superblock on /dev/sdb, missing codepage or helper program, or other error In some cases useful info is found in syslog - try dmesg | tail or so [root@server1 /]# dmesg |tail -5 EXT4-fs (sdb): mounted filesystem with ordered data mode. Opts: EXT4-fs (sdb): ext4_check_descriptors: Checksum for group 0 failed (43116!=0) EXT4-fs (sdb): group descriptors corrupted! EXT4-fs (sdb): ext4_check_descriptors: Checksum for group 0 failed (43116!=0) EXT4-fs (sdb): group descriptors corrupted! [root@server1 /]#

    組描述錯誤可以直接利用fsck –y  device設備名來進行修復,修復好后就能正常掛載 。

    [root@server1 /]# fsck -y /dev/sdb fsck from util-linux-ng 2.17.2 e2fsck 1.41.12 (17-May-2010) fsck.ext4: Group descriptors look bad... trying backup blocks... /dev/sdb was not cleanly unmounted, 強制檢查. 第一步: 檢查inode,塊,和大小 第二步: 檢查目錄結構 第3步: 檢查目錄連接性 Pass 4: Checking reference counts 第5步: 檢查簇概要信息 Free 塊s count wrong for 簇 #48 (24544, counted=24543). 處理? 是 Free 塊s count wrong (2541777, counted=2541776). 處理? 是 Free inodes count wrong for 簇 #48 (8192, counted=8191). 處理? 是 Directories count wrong for 簇 #48 (0, counted=1). 處理? 是 Free inodes count wrong (655349, counted=655348). 處理?/dev/sdb: ***** 文件系統已修改 *****
    /dev/sdb: 12/655360 files (0.0% non-contiguous), 79664/2621440 blocks [root@server1 /]# mount /dev/sdb /data/ [root@server1 /]# df -lh Filesystem Size Used Avail Use% Mounted on /dev/mapper/VolGroup-LogVol01_root  9.9G  4.3G  5.1G  46% / tmpfs 491M 32K 491M 1% /dev/shm /dev/sda1                           194M   35M  150M  19% /boot /dev/mapper/VolGroup-LogVol02_home  7.7G  149M  7.2G   2% /home /dev/sdb                            9.9G  151M  9.2G   2% /data [root@server1 /]#


    免責聲明!

    本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



     
    粵ICP備18138465號   © 2018-2025 CODEPRJ.COM