MDADM 軟體磁碟陣列 RAID 1 使用經驗與心得
用 Software RAID (MDADM) 做 RAID 1 磁碟陣列。
先說明,RAID 1 適合用在全年不關機,又要保持資料即時備份的場合。 不適合常常關機的家用電腦。對常年不關機的家用 NAS,可以說是成本最低的資料保全方案。
本文情境設定的磁碟分割表
設備 | 掛載點 | 容量 | 檔案系統 |
---|---|---|---|
sda1 | /boot/efi | 100 MB | FAT32 |
sda2 | md2 | 512 MB | Ext2 |
sda3 | Swap | 1 GB | swap |
sda4 | md4 | 1000 GB | Ext4 |
sdb1 | 100 MB | FAT32 | |
sdb2 | md2 | 512 MB | Ext2 |
sdb3 | Swap | 1 GB | swap |
sdb4 | md4 | 1000 GB | Ext4 |
md2 | /boot | 512 MB | Ext2 |
md4 | / | 1000 GB | Ext4 |
Boot 和 Root 各組一個 RAID 1 陣列。
- 陣列 /dev/md2 是 /dev/sda2 + /dev/sdb2。
- 陣列 /dev/md4 是 /dev/sda4 + /dev/sdb4。
磁碟故障操作情境
先說明磁碟故障時該怎麼處理。 沒用過 MDADM 的人,請先評估能不能應付這種情形。
磁碟陣列的操作情境都是針對 磁碟可以熱插拔 的情形。 在開機運作過程中,若一個磁碟故障時,管理者先告訴 MDADM 從陣列中移除故障磁碟。 然後管理者就可以拔下故障磁碟換上新的。再告訴 MDADM 新磁碟上線了,讓它在新磁碟上重建資料。 全程不關機,維持電腦全年不關機運作。
「全程不關機」聽起來很美好。但你的電腦機殻上有磁碟抽取設計嗎? 家用或辦公室電腦 (非伺服器型) 都是把磁碟鎖在機殻內部。 你敢在不關機狀態下,打開機殻、拆下磁碟嗎?
機殻設計先不管,再繼續看指令操作過程。注意,本文所有指令,都是用 root 執行。
若第二個磁碟 (sdb) 故障。首先移除故障磁碟:
# mdadm --manage /dev/md2 --remove /dev/sdb2
# mdadm --manage /dev/md4 --remove /dev/sdb4
拔下故障磁碟,換上新的。 這時新磁碟連分割區都沒建,還不能加入陣列。 可以直接複製目前分割區狀態到新磁碟
; MBR分割表用 sfdisk 複製
# sfdisk -d /dev/sda | sfdisk /dev/sdb
; GPT分割表用 sgdisk 複製
# sgdisk /dev/sda --replicate=/dev/sdb
; 隨機設定新的 Partition UUID
# sgdisk -G /dev/sdb
; 格式化新磁碟的置換空間 (/dev/sdb3)
# mkswap /dev/sdb3
手動重建 ESP 與更新 EFI 啟動紀錄。我未將這塊納入 MDADM 管理。
# mkfs.fat -F 32 /dev/sdb1
# mount /dev/sdb1 /mnt
# rsync -a /boot/efi/EFI /mnt
# umount /mnt
; 或者直接用 dd 寫入 ESP
# dd if=/dev/sda1 of=/dev/sdb1
; 查看目前 EFI 紀錄
# efibootmgr -v
Boot0004* EFI Internal Shell
Boot0005* debian HD(1,GPT,db0ae29a-...)/File(\EFI\debian\shimx64.efi)
Boot0006* debian2 HD(1,GPT,c334bd11-...)/File(\EFI\debian\shimx64.efi)
; 移除損壞磁碟(此例是第2個)的 EFI 紀錄 Boot0006
# efibootmgr -B -b 0006
; 將替換磁碟加入 EFI 紀錄
# efibootmgr --create --disk /dev/sdb --part 1 --label "debian2" --loader "\EFI\debian\shimx64.efi"
新磁碟建好分割區加入陣列:
# mdadm --manage /dev/md2 --add /dev/sdb2
# mdadm --manage /dev/md4 --add /dev/sdb4
查看 MDADM 工作狀況,就會看到一行 Rebuild Status ,顯示重建進度。
# cat /proc/mdstat
# mdadm -D /dev/md4
Rebuild Status : ??% complete
在重建過程中,系統可以繼續工作。這是 RAID 1 最主要的好處。
反之,磁碟資料損毀的情形下關機最麻煩。 因為 RAID 1 沒有容錯能力。 在系統重啟後,MDADM 不知道哪個磁碟的資料有問題,你很難預期它會做什麼。 有可能把資料損毀的磁碟當成資料來源,同步到另一個磁碟,使兩個磁碟的資料一起變成不可用。 若你的電腦常常關機,你甚至不要考慮 RAID 1,而要提升到 RAID 5。
系統重啟後,有一個磁碟找不到的情形簡單些。 作業系統開機啟動時會先停住數分鐘。這時就是作業系統在等管理者插入新的磁碟。 你就可以按上面說的步驟,抽換磁碟、重建分割區、加入陣列。
但在生產環境,一般使用者只會覺得卡住開不了機,而想重覆 reboot,悲劇。 如果一直放置不理,開機程序最後就會提示等候逾時,切換到緊急模式。 總之這時就先關機,通知管理者來處理。
系統安裝時就建立 RAID 1
安裝時就準備兩個磁碟。引導到選擇分割區這一步時,必須選手動(Manual),才會看到 Software RAID 項目。
手動切分割區,然後組合陣列。這過程都有安裝程式引導,不必打指令,就不多說。
安裝最後一步,會問要在哪個磁碟上安裝 GRUB。先裝 sda。
如果你的電腦是經由 UEFI 啟動,請看上節的 efibootmgr 操作在 sdb 上建立啟動程式。 電腦經由 BIOS 啟動的話,則等啟動系統後,再下指令 grub-install 安裝一份到 sdb。 但這不是為了 sdb 也能獨立開機。而是為了 sda 故障消失時,可以從 sdb 進入啟動程序,等管理者換上新磁碟。
# grub-install /dev/sdb
# update-grub
fstab 中不歸 RAID 管理的項目 (例如 ESP 和 swap),建議不用 UUID,改成實際設備名稱 (/dev/sda1, /dev/sda3)。 假設故障情境是第一個磁碟 (原 sda) 損壞。 當主機找不到第一個磁碟時,第二個磁碟 (原 sdb) 的設備名稱就會頂替成為 /dev/sda。 原 /dev/sdb1 就會變成 /dev/sda1。 fstab 就能找到繼續用。 如果用 UUID (指向原 sda1),那 fstab 就找不到了。
此外,安裝時在兩個磁碟中各切一個 swap 分割區,你的 fstab 通常會有兩個 swap 項目。 若是你在更換磁碟之後忘了修改 fstab 更新 swap 項目的 UUID,那麼開機會因為找不到 UUID 指定的 swap 而卡住幾分鐘。 改用實際設備名稱,例如本文的 /dev/sda3, /dev/sdb3,就比較省事。
fstab swap 紀錄的建議寫法:
/dev/sda3 none swap sw,nofail 0 0
/dev/sdb3 none swap sw,nofail 0 0
把工作中的分割區轉移到 RAID 1
你安裝系統時只有一個磁碟。日後想要轉移到 RAID 1。
注意,不能直接把一個有資料的磁碟分割區加到 RAID。 因為建立 RAID 的過程,需要格式化 RAID 設備。這會清除原本的資料。 建議事先備份原來的資料。
安裝套件: apt install mdadm rsync
。
情境設定與陣列建立流程:
- sda4 是正在使用、有資料的 Root 分割區。
- 準備另一個分割區 sdb4 ,用來和 sda4 組陣列 md4。
- 你的系統還沒有任何磁碟陣列。先單獨用 sdb4 建立陣列 md4。
- 格式化 md4。如 sdb4 不是全新分割區,那格式化會清除 sdb4 的資料。
- 格式化後,掛載 md4 到 /mnt。
- 將 sda4 (/) 的資料複製到 md4 (/mnt)。通常用 rsync。
- 最後才是將 sda4 組進陣列 md4。
在一個新磁碟上建好分割區 /dev/sdb4。分割區型態 (type of partition) 要選 fd (Linux raid autodetect)。
先用這一個分割區建建立 RAID 1 磁碟陣列,然後格式化陣列。
; 清除 sdb4 的 superblock 資料 (metadata),確保 MDADM 知道這是一個新分割區。
# mdadm --zero-superblock /dev/sdb4
# mdadm --create /dev/md4 --level=1 --raid-disks=2 missing /dev/sdb4
# mkfs.ext4 /dev/md4
規劃是把 sda4 和 sdb4 組成陣列,但現在只能加進 sdb4。 留給 sda4 的位置,就要用 missing 表示。
把 sda4 (/) 的資料複製到陣列 md4:
# mount /dev/md4 /mnt
# rsync -avh --exclude=/{boot,dev,media,mnt,proc,run,sys,tmp}/ / /mnt
# umount /mnt
將 RAID 組合資訊,存入 /etc/mdadm/mdadm.conf。
# mdadm --detail --scan >> /etc/mdadm/mdadm.conf
用指令 blkid
查看各分割區 (含磁碟陣列) 的 UUID。
修改 /etc/fstab ,將原本指向 /dev/sda4 的那一條,改成 /dev/md4。
# 原來的
UUID=sda4的uuid / ext4 errors=remount-ro 0 1
# 改成
UUID=md4的uuid / ext4 errors=remount-ro 0 1
重新啟動主機,讓 /dev/md4 掛載在 / 上。解放 /dev/sda4。
接著為了將 sda4 組進 md4,需要清除 sda4 的資料。對,清除。 我們要變更它的分割區型態為 fd (Linux raid autodetect),這會清除原本分割區上的資料。
操作磁碟分割工具變更 sda4 的分割區型態之後,我們便可將 sda4 加入陣列 md4。 加入後, MDADM 就會開始重建資料。
# mdadm /dev/md4 --add /dev/sda4
; 觀察陣列 md4 的狀態
# mdadm -D /dev/md4
最後觀察陣列 md4 的狀態,確認資料重建進度。 到此就完成將一組分割區轉移到磁碟陣列的工作了。
陣列中的磁碟單獨拿到另一台電腦
如果把陣列的其中一個磁碟單獨拿到另一台工作中的電腦,想要複製裡面的資料。 通常不能直接掛載。
- 先看 /proc/mdstat 確認這個磁碟現在的狀態和名稱。
- 要求 MDADM 停止控制它。
- 告訴 MDADM 單獨跑這個磁碟。
- 可以掛載了。
; 查看狀態
# cat /proc/mdstat
; 假設看到 md4 : inactive sdb4[2]
; 這就是說 md4 磁碟陣列現在未動作,只有一個單位 sdb4 在。
; 停止 md4 磁碟陣列
# mdadm --stop /dev/md4
; 讓 md4 陣列單獨用 sdb4 一個單位跑
# mdadm --assemble --run /dev/md4 /dev/sdb4
# mount /dev/md4 /mnt
把陣列的磁碟單獨拿出來接在另一台電腦上,通常是為了資料救援。 也有人是再插一個新磁碟,在另一台電腦重製系統。嗯,也行啦。