RAID - Arch Linux 中文维基

跳至內容

# RAID

出自 Arch Linux 中文维基
翻譯狀態：

- 本文（或部分內容）譯自 RAID，最近一次同步於 2025-07-15，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

相關文章

- LVM on software RAID
- LVM#RAID
- Install Arch Linux with Fake RAID
- Convert a single drive system to RAID
- ZFS
- ZFS/虛擬磁碟
- Swap#分片
- Btrfs#RAID

獨立磁碟冗餘陣列 (Redundant Array of Independent Disks，RAID) 是一種將多個磁碟驅動器組件（通常是多塊硬碟或多個分區）組合為一個邏輯單元的存儲技術。根據 RAID 的部署情況，這個邏輯單元可以是單個的文件系統，也可以是一個能在其上建立多個分區的透明中間層。

根據所需的冗餘量和性能要求，數據按照 #RAID 級別中的某一種方式分布在驅動器中。所選的 RAID 級別決定了是否可以防止數據丟失（硬碟故障時）、是否提高性能或結合兩者優勢。

本文介紹如何使用 mdadm(8) 創建並管理一個軟體磁碟陣列。

警告：確保在操作前備份所有數據。

## RAID 級別

儘管大部分 RAID 級別都或多或少地包含了數據冗餘，RAID 並不能完全保證數據安全。如果遇到火災、計算機被盜或者多塊硬碟同時損壞，RAID 將無法保護數據。此外，配置一個帶有 RAID 的系統是一個複雜的過程，可能會破壞現有數據。

### 基本 RAID 級別

有多種不同的基本 RAID 級別，下面列出了最常用的幾種。

RAID 0
  將多塊硬碟組合為一個條帶卷'並不提供數據冗餘（實際上會降低可靠性），但它仍可以被當做是 RAID，而且它確實提供了巨幅的速度提升。如果提高速度比數據安全更重要（比如作為 swap 分區），可以選擇這種 RAID 級別。在伺服器上，RAID 1 和 RAID 5 陣列更加合適。在 RAID 0 陣列中，塊設備的大小是最小組成分區的大小乘以組成分區的數量。

RAID 1
  這是最直接的 RAID 級別：完全鏡像。與其他 RAID 級別一樣，它只在分區位於不同物理硬碟上才有效。如果某一塊硬碟損壞，由 RAID 陣列提供的塊設備將不受影響。可以使用 RAID 1 的情境包括了除 swap 和臨時文件外的其他所有情境。請注意，如果使用由軟體實現的 RAID，引導分區只能選擇 RAID 1，因為讀取引導分區的引導器通常無法辨識 RAID，但一個 RAID 1 的組成分區可以像常規分區一樣讀取。RAID 1 陣列塊設備的大小是最小組成分區的大小。

RAID 5
  需要至少 3 塊物理硬碟，並結合了 RAID 1 的數據冗餘和 RAID 0 的速度與可用空間上的優勢。RAID 5 使用了類似 RAID 0 的條帶化技術，同時也將奇偶校驗塊分布式地存儲在每一塊磁碟上。如果遭遇硬碟損壞，這些奇偶校驗塊就可以用來在替代的新磁碟上重建損壞的數據。RAID 5 僅可彌補一個組成磁碟損壞帶來的損失。
  注意：RAID 5 是結合了速度與數據冗餘優勢的常用選擇。但值得注意的是，當一塊硬碟損壞而沒有及時更換，此時若再有硬碟損壞，則所有數據都將丟失。此外，考慮到現代磁碟的超大容量和消費級硬碟無法恢復的讀取錯誤率 (Unrecoverable read error, URE)，超過 4TiB 的陣列在重建數據時出現至少一處讀取錯誤 (URE) 的概率幾乎在預料之中（概率大於 50%）。因此，存儲行業不再推薦使用 RAID 5。

RAID 6
  需要至少 4 塊物理硬碟，提供了和 RAID 5 一樣的優勢並且在兩塊硬碟損壞時仍能保證數據安全。RAID 6 使用了和 RAID 5 類似的條帶化技術，但是把兩個不同的奇偶校驗塊分布式地存儲在每一塊磁碟上。如果磁碟發生故障，這些奇偶校驗塊將用於重建替換磁碟上的數據。RAID 6 可以承擔兩個組成磁碟的損失。在抵禦無法恢復的讀取錯誤 (Unrecoverable read error, URE) 時也某種程度上更加可靠，因為磁碟陣列在重建某一塊損壞硬碟的數據時仍然有奇偶校驗塊可以校驗數據。但是，總體而言，RAID 6 開銷較大，大多數時候 far2 布局的 RAID 10（參見下文）提供了更快的速度和更強的可靠性，因此更傾向於採用 RAID 10。

### 嵌套 RAID 級別

RAID 1+0
  RAID1+0 是一種結合了兩種基本 RAID 級別的嵌套級別，它相對基本級別提高了性能且增加了冗餘量。它通常被稱為 RAID10，但是，Linux MD（內核自帶的 RAID 實現）支持的 RAID10 不是簡單的兩層 RAID 重疊，請看下文。

RAID 10
  Linux 下的 RAID10 建立在 RAID1+0 的概念上，但它將其實現為單一的一層，這一層可以有多種不同的布局。可參考創建複雜 RAID 10。
  在 Y 塊硬碟上的近 X 布局在不同硬碟上重複儲存每個數據塊 X 次，但不需要 Y 可以被 X 整除。數據塊放在所鏡像的磁碟上幾乎相同的位置，這就是近布局名字的來源。它可以工作在任意數量的磁碟上，最少是 2 塊。在 2 塊硬碟上的近 2 布局相當於 RAID1，4 塊硬碟上的近 2 布局相當於 RAID1+0。
  在 Y 塊硬碟上的遠 X 布局設計用於在鏡像陣列中提供與條帶化技術一樣快的讀取速度。它通過把每塊硬碟分成前後兩部分來實現這一點，寫入第一塊硬碟前半部分數據也會寫入第二塊硬碟的後半部分，反之亦然。這樣可以達到一個效果，那就是把對連續數據的讀取條帶化，而這正是 RAID0 和 RAID5 讀取性能高的原因。它的缺點在於寫入連續數據時有輕微性能損失，因為硬碟磁頭要運動到另一片區域來寫入鏡像。當數據讀取性能和可用性/冗餘性一樣重要時，比起 RAID1+0 和 RAID5，更應該優先考慮遠 2 布局的 RAID10。需注意這種方式仍無法代替備份。詳情請閱讀維基百科相關頁面。

警告：mdadm cannot reshape arrays in far X layouts which means once the array is created, you will not be able to `mdadm --grow` it. For example, if you have a 4x1TB RAID10 array and you want to switch to 2TB disks, your usable capacity will remain 2TB. For such use cases, stick to near X layouts.

### RAID 級別對比

RAID 級別 | 數據冗餘 | 物理設備利用率 | 讀取性能 | 寫入性能 | 最少磁碟數量
--- | --- | --- | --- | --- | ---
0 | 否 | 100% | n 倍 最優 | n 倍 最優 | 2
1 | 是 | 50% | 如果有多個進程同時讀取，最多 n 倍，否則 1 倍 | 1 倍 | 2
5 | 是 | 67% - 94% | (n−1) 倍 較優 | (n−1) 倍 較優 | 3
6 | 是 | 50% - 88% | (n−2) 倍 | (n−2) 倍 | 4
10,far2 | 是 | 50% | n 倍 最優; 與 RAID0 相當但加入了數據冗餘 | (n/2) 倍 | 2
10,near2 | 是 | 50% | 如果有多個進程同時讀取，最多 n 倍，否則 1 倍 | (n/2) 倍 | 2

* 其中 n 表示用於組成陣列的磁碟數量。

### LINEAR

LINEAR allows to map two or more devices into a single device, without parallel accesses like RAID0 but allowing to fully use disks from different sizes. To create a pseudo RAID using this mode without mdadm, one can either use the low-level dmsetup(8) utility, the high-level LVM framework or the Btrfs filesystem.

## 實現方式

RAID 設備可以用不同方式來管理：

軟體 RAID
  這是最簡單的實現方式，因為它不依賴於專用固件或專有軟體。這種陣列由作業系統通過以下方式進行管理：
  - 通過抽象層管理（比如 mdadm）；
    注意：這是在本指南下文將要使用的方法。
  - 通過邏輯卷管理器來管理（比如 LVM）；
  - 通過文件系統的某個組件來管理（比如 ZFS，Btrfs）。

硬體 RAID
  這種陣列由安裝在計算機上的專用硬體卡直接管理，硬碟直接連接在該計算機上。RAID 的處理邏輯由板載的處理器完成，它獨立於主處理器 (CPU)。儘管這種方案獨立於任何作業系統，但卻需要驅動程序來使硬體 RAID 控制器正常工作。取決於不同的製造商，硬體 RAID 陣列可以在 option ROM 裡設置或者作業系統安裝完成後另行安裝配套軟體來設置。這種設置是獨立於 Linux 內核的：內核並不能看到單獨的每塊硬碟。

FakeRAID
  這種類型的 RAID 應當稱為 BIOS 或板載 RAID，卻常被錯誤地當做硬體 RAID 來宣傳。這種陣列由偽 RAID 控制器來管理，RAID 邏輯由 option ROM 或在 UEFI 情況下由安裝了 EFI Sata 驅動程序的固件本身來完成，但並不是實現了所有 RAID 功能的完整硬體 RAID 控制器。因此，這種 RAID 有時被稱為 FakeRAID。dmraid包 會被用於處理這種控制器。這裡列出一些 FakeRAID 控制器：Intel Rapid Storage，JMicron JMB36x RAID ROM，AMD RAID，ASMedia 106x 和 NVIDIA MediaShield。

### 我正在使用哪一種 RAID？

由於軟體 RAID 是由用戶部署的，因此用戶很容易就知道 RAID 的類型。

但是，辨別 FakeRAID 和真正的硬體 RAID 是很困難的。如上所述，製造商經常錯誤地混淆這兩種類型的 RAID，還可能進行虛假宣傳。這種情況下應該採取的最好方式是運行 `lspci` 命令並在輸出信息中找到你的 RAID 控制器，然後根據這些信息進行更進一步的搜索。硬體 RAID 控制器會在這一列表中出現，但 FakeRAID 不會。同時，真正的硬體 RAID 控制器通常價格很高，如果這個系統是自行組裝的，那麼很可能安裝一個硬體 RAID 會使電腦的價格顯著提高。

## 安裝

安裝 mdadm包。mdadm 用於管理在純塊設備上建立起來的純軟體 RAID：底層硬體不提供任何 RAID 邏輯，只是一些磁碟而已。mdadm 可以在任何塊設備集合上工作，甚至是那些非常規的設備。比如，你可以用一堆 U 盤來建立 RAID 陣列。

### 準備設備

警告：這些步驟會擦除指定設備上的所有數據，輸入命令請小心！

如果設備是舊設備重用或剛從一個現有的陣列上拆下來，請擦除所有舊的 RAID 配置信息：

     # mdadm --misc --zero-superblock /dev/drive

或者是刪除設備上的某個特定的分區：

     # mdadm --misc --zero-superblock /dev/partition

注意：

- 清除一個分區的 superblock 不會影響到磁碟上的其他分區。
- 考慮到 RAID 本身的功能特點，在運行中的磁碟陣列中完全地 安全擦除磁碟 是很困難的。請在創建陣列前考慮要不要安全擦除磁碟。
- You can do the whole disk preparation procedure from a GUI with blivet-guiAUR.

### 對磁碟進行分區

強烈推薦對用於陣列的硬碟進行分區。考慮到大多數 RAID 用戶會用到超過 2 TiB 的硬碟，因此推薦並要求使用 GPT。參閱分區獲取關於磁碟分區的更多信息以及可供使用的分區工具。

注意：也可以在裸磁碟（沒有分區的磁碟）上直接創建 RAID，但不推薦這麼做，因為這樣可能會導致更換損壞硬碟時出現問題
注意：當更換 RAID 中的某塊損壞的硬碟時，新硬碟的大小必須恰好等於或大於損壞的硬碟，否則無法完成陣列重建過程。即使是同一廠商相同型號的硬碟也可能有容量上的細微差別。通過在磁碟末尾保留一些未分配的空間可以消除磁碟容量上的細微差異，這樣可以使替代磁碟的型號選擇更加容易。因此，最好在磁碟末尾留出大約 100 MiB 的未分配空間。

#### GUID 分區表

- 創建分區以後，這些分區的類型標識符 (GUID) 應該是 `A19D880F-05FC-4D3B-A006-743F0F84911E`（在 fdisk 裡將分區類型改為 `Linux RAID` 或在 gdisk 裡改為 `FD00` 可以給所選分區分配這個標識符）。
- 如果使用了一個更大的磁碟陣列，可以考慮分配文件系統標籤[損壞的連結：無效的章節] 或分區標籤[損壞的連結：無效的章節] 用於以後區分每塊單獨的硬碟。
- 建議在每個設備上創建大小相同的分區。

#### 主引導記錄 (MBR)

對於在使用 MBR 的硬碟上創建分區的用戶，可用的分區類型 ID 包括：

- `0xDA`：無文件系統（fdisk 中稱為 `Non-FS data`）。這是推薦用於 Arch Linux 上 RAID 陣列的 mdadm 分區類型。
- `0xFD`：自動檢測的 RAID（fdisk 中稱為 `Linux RAID autodetect`）。This partition type should only be used if RAID autodetection is desireable (non-initramfs system, old mdadm metadata format).

更多信息請參閱 Linux Raid Wiki:Partition Types。

### 創建陣列

使用 `mdadm` 來創建陣列。參閱 mdadm(8) 獲取支持的選項。下面列出部分使用範例。

警告：不要簡單地複製/粘貼下面的示例，確保你已經使用正確的選項和設備名稱替代了示例中相應的內容。
注意：

- 如果有一個從 Syslinux 啟動的 RAID1 陣列，在 syslinux v4.07 中要求元數據值為 1.0，而不是默認的 1.2。
- 當用 Arch 安裝鏡像 創建磁碟陣列時，請使用 `--homehost=yourhostname` 選項設置 主機名（或者 `--homehost=any` 選項無論在什麼主機上都用相同的主機名），否則主機名稱 `archiso` 會被寫入陣列的元數據中。

提示：要為 RAID 設備指定一個自定義的名稱，可以使用 `--name=MyRAIDName` 選項或將 RAID 設備路徑改為 `/dev/md/MyRAIDName`。Udev 會使用該名稱創建指向 `/dev/md/` 內 RAID 陣列的符號連結。如果 `homehost` 與當前 主機名 匹配（或者 homehost 設為了 `any`）則連結將會是 `/dev/md/name`，如果 homehost 不匹配那麼連結將會是 `/dev/md/homehost:name`。

下面這個例子展示了在 2 個設備上建立 RAID1 陣列：

     # mdadm --create --verbose --level=1 --raid-devices=2 /dev/md/MyRAID1Array /dev/sdb1 /dev/sdc1

下面這個例子展示了使用 4 塊磁碟作為工作 (active) 磁碟，1 塊作為備用 (spare) 磁碟建立 RAID5 陣列：

     # mdadm --create --verbose --level=5 --raid-devices=4 /dev/md/MyRAID5Array /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1 --spare-devices=1 /dev/sdf1

提示：`--chunk` 可用於修改默認的區塊大小。更多關於優化區塊大小的內容請參閱 Chunks: the hidden key to RAID performance。

下面這個例子展示了在 2 個設備上建立遠 2 布局的 RAID10 陣列 (RAID10, far2)：

     # mdadm --create --verbose --level=10 --raid-devices=2 --layout=f2 /dev/md/MyRAID10Array /dev/sdb1 /dev/sdc1

這樣，陣列就會在虛擬設備 `/dev/mdX` 下建立起來，容量已經合併且可以使用（但處於降級模式）。mdadm 在後台同步數據時你已經可以直接開始使用這個陣列了。儲存奇偶校驗位可能要花很長時間，可以用這個命令查看進度：

    $ cat /proc/mdstat

### 更新配置文件

默認情況下，`mdadm.conf` 中的大部分內容都被注釋掉了，它應該只包含如下內容：

    /etc/mdadm.conf

    ...
    DEVICE partitions
    ...

這一指令告訴 mdadm 檢查由 `/proc/partitions` 引用的所有設備並儘可能將其中的陣列組合起來。如果你確實想啟動所有可用的陣列並且確信不存在意料之外的超級塊（比如安裝了新的存儲設備），那麼這樣的配置就很好。當然有一種更精準的控制方法，就是顯式地將陣列添加到 `/etc/mdadm.conf`：

    # mdadm --detail --scan >> /etc/mdadm.conf

這將會在配置中添加類似這樣的內容：

    /etc/mdadm.conf

    ...
    DEVICE partitions
    ...
    ARRAY /dev/md/MyRAID1Array metadata=1.2 name=pine:MyRAID1Array UUID=27664f0d:111e493d:4d810213:9f291abe

這也會使 mdadm 檢查由 `/proc/partitions` 引用的設備。但是，只有超級塊的 UUID 是 `27664…` 的設備才會被組合成激活的陣列。

更多信息請參閱 mdadm.conf(5)。

### 組合成磁碟陣列

更新配置文件後即可用 mdadm 組合磁碟陣列：

    # mdadm --assemble --scan

### 格式化 RAID 上的文件系統

提示：To create multiple volumes inside a RAID array, follow the LVM on software RAID article.

現在磁碟陣列已經可以像普通分區一樣被格式化成某個文件系統，但要記住：

- 不是所有文件系統都支持超大分區（參閱 Wikipedia:Comparison of file systems#Limits）。
- 文件系統需要支持在線增大和收縮（參閱 Wikipedia:Comparison of file systems#Features）。
- 應合理計算跨度大小和帶區寬度來獲得最佳性能。

#### 計算 stride（跨度大小）和 stripe width（帶區寬度）

優化文件系統結構以適應底層 RAID 結構需要 2 個參數：stride 和 stripe width。它們對應於 RAID 的 chunk size（區塊大小）、文件系統的 block size（塊大小）以及 "data disks"（數據盤）的數量。

Chunk size（RAID 區塊大小）是 RAID 陣列的一個屬性，在陣列創建時就已經定好了。目前 `mdadm` 默認該值為 512 KiB。這個參數可以用 `mdadm` 讀取：

    # mdadm --detail /dev/mdX | grep 'Chunk Size'

Block size（塊大小）是文件系統的一個屬性，在文件系統創建時就已經定好了。在大部分文件系統上（包括 ext4）默認是 4 KiB。更多關於當前系統 ext4 的信息可以查看 `/etc/mke2fs.conf` 文件。

"Data disks"（數據盤）的數量指的是陣列能夠完全重建數據所要求的最少可用設備。例如，對於 N 個設備的 raid0 來說這個數量是 N，對於 raid5 來說是 N-1。

當你獲得了這三個參數時，stride 和 stripe width 可以用下列公式來計算：

    stride = chunk size / block size
    stripe width = number of data disks * stride

##### 範例 1. RAID0

本範例使用了正確的 stride 和 stripe width 將合併後的分區格式化成了 ext4：

- 假設這一 RAID0 陣列是由 2 塊物理硬碟組成的。
- Chunk size（RAID 區塊大小）是 512 KiB。
- Block size（文件系統塊大小）是 4 KiB。

因為 stride = chunk size / block size。在這個例子中，stride 大小是 512/4 = 128。

因為 stripe width = # of physical data disks * stride。在這個例子中，stripe width 的大小是 2*128 = 256。

     # mkfs.ext4 -v -L myarray -b 4096 -E stride=128,stripe-width=256 /dev/md0

##### 範例 2. RAID5

本範例使用了正確的 stride 和 stripe width 將合併後的分區格式化成了 ext4：

- 假設這一 RAID5 陣列由 4 塊物理硬碟組成，3 塊是數據盤，1 塊是奇偶校驗盤。
- Chunk size（RAID 區塊大小）是 512 KiB。
- Block size（文件系統塊大小）是 4 KiB。

因為 stride = chunk size / block size。在這個例子中，stride 大小是 512/4 = 128。

因為 stripe width = # of physical data disks * stride。在這個例子中，stripe width 的大小是 3*128 = 384.

     # mkfs.ext4 -v -L myarray -b 4096 -E stride=128,stripe-width=384 /dev/md0

關於 stride 和 stripe width 的更多信息，請參閱：RAID Math。

##### 範例 3. RAID10,far2

本範例使用了正確的 stride 和 stripe width 將合併後的分區格式化成了 ext4：

- 假設這一 RAID10 陣列由 2 塊物理硬碟組成。考慮到遠 2 布局的 RAID10 的自身特性，兩塊硬碟都是數據盤。
- Chunk size（RAID 區塊大小）是 512 KiB。
- Block size（文件系統塊大小）是 4 KiB。

因為 stride = chunk size / block size。 在這個例子中，stride 大小是 512/4 = 128。

因為 stripe width = # of physical data disks * stride。 在這個例子中，stripe width 的大小是 2*128 = 256。

     # mkfs.ext4 -v -L myarray -b 4096 -E stride=128,stripe-width=256 /dev/md0

## 在 Live CD 中掛載 RAID

如果你需要在 Live CD 中掛載 RAID 分區，用這個命令：

     # mdadm --assemble /dev/mdnumber /dev/disk1 /dev/disk2 /dev/disk3 /dev/disk4

如果缺一塊盤的 RAID 1 被錯誤地識別為了 RAID 1（參照 `mdadm --detail /dev/mdnumber`）並報告為非活動狀態（參照 `cat /proc/mdstat`），需要先停止磁碟陣列：

     # mdadm --stop /dev/mdnumber

## 在 RAID 上安裝 Arch Linux

注意：本節僅適用於根文件系統在磁碟陣列上的情況。如果你的磁碟陣列上只是一個數據分區，那麼可以跳過本節。

你應該在安裝過程中的分區和格式化步驟之間創建 RAID 陣列。這將會把一個位於 RAID 陣列上的分區格式化成根文件系統，而不是直接格式化一個分區。 按照 #安裝一節的步驟創建 RAID 陣列。，然後繼續安裝過程，直到 pacstrap 步驟完成。 當使用 UEFI 啟動時，還需要閱讀 EFI 系統分區#ESP在軟RAID1上。

### 更新配置文件

注意：這些操作應該在 chroot 以外完成，因此要在文件路徑前加上 `/mnt`。

在基本系統安裝完成以後，RAID 的默認配置文件 `mdadm.conf` 需要這樣來更新：

    # mdadm --detail --scan >> /mnt/etc/mdadm.conf

在運行這個命令以後一定要用文本編輯器檢查 `mdadm.conf` 配置文件來確保它的內容看起來是合理的。

注意：為防止系統啟動時 `mdmonitor.service` 啟動失敗（由 udev 啟動），你需要取消 `MAILADDR` 的注釋，並且在 `mdadm.conf` 結尾留下可處理磁碟陣列出錯通知的郵件地址和/或應用程式。參閱 #啟用事件郵件通知。

現在繼續安裝過程直到 安裝指南#關於 initramfs 步驟之前為止，然後按照下一節的步驟做。

### 配置 mkinitcpio

注意：這些操作應該在 chroot 時完成。

安裝 mdadm包，並向 `mkinitcpio.conf` 中的鉤子數組添加 `mdadm_udev` 來為初始化內存檔添加 mdadm 支持：

    /etc/mkinitcpio.conf

    ...
    HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block mdadm_udev filesystems fsck)
    ...

然後重新生成初始化內存檔。

注意：每次修改 `/etc/mdadm.conf` 都需要重新生成 initramfs。

### 配置引導加載器

#### 根設備

將 `root` 參數指向映射的磁碟，例如：

    root=/dev/md/MyRAIDArray

如果按上述用內核設備節點來指定映射磁碟的方法之後，從軟體 RAID 分區啟動失敗了，那就用塊設備持久化命名中的某種方法來指定映射的磁碟，例如：

    root=LABEL=Root_Label

參考 GRUB#RAID。

#### RAID0 layout

注意：This also affects existing mdraid RAID0 users that upgrade from an older version of the Linux kernel to 5.3.4 or newer.

Since version 5.3.4 of the Linux kernel, you need to explicitly tell the kernel which RAID0 layout should be used: RAID0_ORIG_LAYOUT (`1`) or RAID0_ALT_MULTIZONE_LAYOUT (`2`).[1] You can do this by providing the kernel parameter as follows:

    raid0.default_layout=2

The correct value depends upon the kernel version that was used to create the raid array: use `1` if created using kernel 3.14 or earlier, use `2` if using a more recent version of the kernel. One way to check this is to look at the creation time of the raid array:

    mdadm --detail /dev/md1

    /dev/md1:
               Version : 1.2
         Creation Time : Thu Sep 24 10:17:41 2015
            Raid Level : raid0
            Array Size : 975859712 (930.65 GiB 999.28 GB)
          Raid Devices : 3
         Total Devices : 3
           Persistence : Superblock is persistent

           Update Time : Thu Sep 24 10:17:41 2015
                 State : clean
        Active Devices : 3
       Working Devices : 3
        Failed Devices : 0
         Spare Devices : 0

            Chunk Size : 512K

    Consistency Policy : none

                  Name : archiso:root
                  UUID : 028de718:20a81234:4db79a2c:e94fd560
                Events : 0

        Number   Major   Minor   RaidDevice State
           0     259        2        0      active sync   /dev/nvme0n1p1
           1     259        6        1      active sync   /dev/nvme2n1p1
           2     259        5        2      active sync   /dev/nvme1n1p2

Here we can see that this raid array was created on September 24, 2015. The release date of Linux Kernel 3.14 was March 30, 2014, and as such this raid array is most likely created using a multizone layout (`2`).

## 維護 RAID

### 數據清掃 (Scrubbing)

定期運行數據清掃 (Scrubbing) 來檢查並修復錯誤是一種很好的做法。一次完整數據清掃可能會花費數個小時，具體取決於磁碟陣列的大小和配置。

啟動數據清掃：

    # echo check > /sys/block/mdX/md/sync_action

數據檢查操作會掃描驅動器來檢查壞扇區並自動修復它們。如果找到了包含損壞數據的好扇區（本扇區中的數據與另一塊硬碟中記錄本扇區應有的數據不符，例如奇偶校驗塊和另一塊數據塊相結合可以證明本數據塊是錯誤的），那就不動作，但記錄下這一事件（見下文）。這種「不動作」允許管理員自行檢查壞扇區中原本的數據和從冗餘數據中重建的數據，然後決定保留哪個。

與許多 mdadm 相關的任務/事項一樣，數據清掃的進度也可以通過查看 `/proc/mdstat` 文件來查詢。

例如：

    $ cat /proc/mdstat

    Personalities : [raid6] [raid5] [raid4] [raid1]
    md0 : active raid1 sdb1[0] sdc1[1]
          3906778112 blocks super 1.2 [2/2] [UU]
          [>....................]  check =  4.0% (158288320/3906778112) finish=386.5min speed=161604K/sec
          bitmap: 0/30 pages [0KB], 65536KB chunk

安全地停止當前的數據清掃操作：

    # echo idle > /sys/block/md0/md/sync_action

注意：如果在數據清掃暫停時重啟了系統，將繼續進行清掃。

數據清掃完成後，管理員可以檢查有多少數據塊（如果有的話）被標記為壞塊：

    # cat /sys/block/md0/md/mismatch_cnt

#### 關於數據清掃的一般說明

注意：用戶也可以 echo repair 到 `/sys/block/md0/md/sync_action` 裡面，但是這是不明智的，因為一旦遇到數據不一致就被自動改寫為一致。危險之處在於我們實際並不知道奇偶校驗塊和數據塊哪個是對的（在 RAID1 中是不知道哪個數據塊是對的）。因此自動清掃操作能不能用正確數據替換錯誤數據取決於運氣。

以 root 身份設定一個 cron 任務來定期執行清掃是很好的。raid-checkAUR 會對此有所幫助。如果要用 systemd 定時器而不是 cron 來執行定期清掃，raid-check-systemdAUR 中包含了相同的腳本和配套的 systemd 定時器單元文件。

注意：對於常規的大容量驅動器，清掃工作耗時大約 6 秒每 GB（即每 TB 大約需要 1 小時 45 分鐘），因此應合理確定 cron 任務或定時器的開始時間。

#### 對清掃 RAID1 和 RAID10 的說明

由於 RAID1 和 RAID10 本質上就是沒有數據緩衝的，所以即使陣列工作正常，它的不匹配計數仍然可能是個非零值。這些不匹配計數隻存在於正在寫入數據的區域，且它們不反映任何問題。但是，我們無法區分非零的不匹配計數到底代表正在寫入數據還是確實存在問題。這是造成 RAID1 和 RAID10 陣列誤報錯誤的根源。即使如此，仍然建議定期清掃以發現並糾正驅動器上可能出現的壞扇區。

### 從陣列中移除設備

要從陣列中移除一個塊設備，先將這個設備標記為 faulty（故障）：

     # mdadm --fail /dev/md0 /dev/failing_array_member

現在從陣列中移除這個設備：

     # mdadm --remove /dev/md0 /dev/failing_array_member

If the device has not failed entirely, but you would like to replace it, e.g. because it looks like it is dying, you can actually handle replacement more gracefully by first adding a new drive and then telling mdadm to replace it.

For example, with `/dev/sdc1` as the new one and `/dev/sdb1` as the failing one:

    # mdadm /dev/md0 --add /dev/sdc1
    # mdadm /dev/md0 --replace /dev/sdb1 --with /dev/sdc1

The `--with /dev/sdc1` part is optional, but more explicit. See [2] for more details.

永久移除設備（比如想把一個設備拿出來單獨使用）： 先使用上述兩個命令，然後：

    # mdadm --zero-superblock /dev/failing_array_member

警告：

- 不要在 RAID0 陣列或者其他線性存放數據的陣列中進行這個操作！否則數據會丟失！
- 重新使用已經移除的硬碟卻不清除它的超級塊將會導致下次啟動時丟失所有數據。（因為 mdadm 將會把它當做磁碟陣列的一部分來使用）。

停止使用某個陣列：

1. 卸載 (umount) 目標陣列
2. 用這個命令停止磁碟陣列運行：`mdadm --stop /dev/md0`
3. 將本節開頭的三個命令在每塊硬碟上都運行一遍。
4. 將 `/etc/mdadm.conf` 中的相關行移除。

### 向陣列中添加設備

可以在系統正在運行且設備已經掛載的情況下使用 mdadm 添加新設備。 按照前文所述的方法，使用現有陣列中相同的布局對新設備進行分區。

如果 RAID 陣列尚未組合，先組合它們：

    # mdadm --assemble /dev/md0 /dev/sda1 /dev/sdb1

向陣列中添加新設備：

    # mdadm --add /dev/md0 /dev/sdc1

這一步 mdadm 不會花費很長時間。

這篇文章的某些內容需要擴充。

原因：A `--backup-file` should be created prior to `grow` (在 Talk:RAID#Add a drive (RAID5, RAID6) 中討論)

根據不同的 RAID 類型（比如 RAID1），mdadm 可能會把部分設備添加為備用設備，而不在這些設備上存放數據。可以使用 `--grow` 加上 `--raid-devices` 選項來增加 RAID 利用的磁碟數量。例如，將一個陣列增加至四塊硬碟：

    # mdadm --grow /dev/md0 --raid-devices=4

可以這樣檢查進度：

    # cat /proc/mdstat

用這個命令檢查已經添加的設備：

    # mdadm --misc --detail /dev/md0

注意：對於 RAID0 設備可能會收到以下錯誤信息：

    mdadm: add new device failed for /dev/sdc1 as 2: Invalid argument

這是由於上述命令會將新磁碟添加為 "spare"（備用）盤，但是 RAID0 中不存在備用盤。如果想往 RAID0 陣列中添加磁碟，你需要同時使用 "grow" 和 "add" 參數。如下所示：

    # mdadm --grow /dev/md0 --raid-devices=3 --add /dev/sdc1

### 增大 RAID 卷的大小

如果給陣列安裝了更大的磁碟，或者增大了分區大小，可能就需要增大 RAID 卷的大小以適應更大的可用空間。這一過程可用首先按照上文中關於更換磁碟的步驟來做。當 RAID 卷在更大的磁碟上重建完成後，這個卷需要 "grow" 來填充多出來的空間。

    # mdadm --grow /dev/md0 --size=max

接著，在 RAID 卷 `/dev/md0` 上的現有分區可能需要調整大小。參閱分區獲取更多信息。最後，上述分區上的文件系統也需要重新調整大小。如果用 `gparted` 來完成分區操作，這些都會自動完成。如果用的是其他工具，請手動卸載 (unmount) 文件系統並調整其大小。

    # umount /storage
    # fsck.ext4 -f /dev/md0p1
    # resize2fs /dev/md0p1

### 修改同步速度限制

同步工作需要一定的時間。如果本機不需要完成其他任務，可以提高速度限制值。

    # cat /proc/mdstat

     Personalities : [raid10]
     md127 : active raid10 sdd1[3] sdc1[2] sdb1[1] sda1[0]
         31251490816 blocks super 1.2 512K chunks 2 far-copies [4/4] [UUUU]
         [=>...................]  resync =  5.2% (1629533760/31251490816) finish=2071.7min speed=238293K/sec
         bitmap: 221/233 pages [884KB], 65536KB chunk

In the above example, it would seem the max speed is limited to approximately 238 M/sec.

查看當前速度限制（單位為 KiB/s）：

    # sysctl dev.raid.speed_limit_min

    dev.raid.speed_limit_min = 1000

    # sysctl dev.raid.speed_limit_max

    dev.raid.speed_limit_max = 200000

Set a new maximum speed of raid resyncing operations using sysctl:

    # sysctl -w dev.raid.speed_limit_min=600000
    # sysctl -w dev.raid.speed_limit_max=600000

然後查看同步速度和預計完成時間：

    # cat /proc/mdstat

      Personalities : [raid10]
     md127 : active raid10 sdd1[3] sdc1[2] sdb1[1] sda1[0]
         31251490816 blocks super 1.2 512K chunks 2 far-copies [4/4] [UUUU]
         [=>...................]  resync =  5.3% (1657016448/31251490816) finish=1234.9min speed=399407K/sec
         bitmap: 221/233 pages [884KB], 65536KB chunk

### RAID5 performance

To improve RAID5 performance for fast storage (e.g. NVMe), increase `/sys/block/mdx/md/group_thread_cnt` to more threads. For example, to use 8 threads to operate on a RAID5 device:

    # echo 8 > /sys/block/md0/md/group_thread_cnt

See git kernel commit 851c30c9badf.

### Update RAID superblock

To update the RAID superblock, you need to first unmount the array and then stop the array with the following command:

    # mdadm --stop /dev/md0

Then you can update certain parameters by reassembling the array. For example, to update the `homehost`:

    # mdadm --assemble --update=homehost --homehost=NAS /dev/md0 /dev/sda1 /dev/sdb1

See the arguments of `--update` for details.

## 監視運行情況

可以顯示當前 RAID 設備狀態的一行簡單命令：

    # awk '/^md/ {printf "%s: ", $1}; /blocks/ {print $NF}' </proc/mdstat

    md1: [UU]
    md0: [UU]

### 用 watch 監視 mdstat

    # watch -t 'cat /proc/mdstat'

或者最好用 tmux包

    # tmux split-window -l 12 "watch -t 'cat /proc/mdstat'"

### 用 iotop 追蹤 IO

iotop包 可以顯示各個進程的輸入輸出狀態。請用這個命令來查看 RAID 線程的輸入輸出。

     # iotop -a $(sed 's/^/-p /g' <<<`pgrep "_raid|_resync|jbd2"`)

### 用 iostat 追蹤 IO

sysstat包 包中的 iostat 實用程序可以顯示各個設備和分區的輸入輸出統計。

    # iostat -dmy 1 /dev/md0
    # iostat -dmy 1 # all

### mdadm via systemd

mdadm provides the systemd service `mdmonitor.service` which can be useful for monitoring the health of your raid arrays and notifying you if anything goes wrong.

This service is special in that it cannot be manually activated like a regular service; mdadm will take care of activating it via udev upon assembling your arrays on system startup, but it will only do so if an email address and/or program has been configured for its notifications (see below).

### 啟用事件郵件通知

mdadm 提供了名為 `mdmonitor.service` 的 systemd 服務，可幫助監控 RAID 陣列的健康度，並在出現問題時通過郵件通知你。

這個服務較為特殊，它無法用通常的方法來激活；僅在 mdadm 按下面的步驟為通知配置郵件地址後，它才會在系統啟動階段組裝陣列時，通過 udev 激活該服務。

警告：郵件地址配置錯誤會導致監控服務啟動靜默失敗。
注意：在發送郵件前，需要有一個配置好的郵件傳輸代理。

通過編輯 `/etc/mdadm.conf` 並配置郵件地址來啟用該功能：MAILADDR user@domain

接下來，通過如下命令來驗證功能是否正常：

    # mdadm --monitor --scan --oneshot --test

如果測試成功並郵件正常送達，則配置完成；在下次陣列完成組裝時，`mdmonitor.service` 將開始監控陣列錯誤。

#### Program notifications

Like Email notification above, edit `/etc/mdadm.conf` and edit the line:

    PROGRAM /usr/sbin/handle-mdadm-events

The argument for PROGRAM is the script you want to run for any event. Which then interact with proper network monitoring agents. Or even IM clients or push notification services like ntfy.sh for home users.

Test in the same way as for email notification above.

## 故障排除

如果你在重啟計算機時遇到類似 "invalid raid superblock magic" 的錯誤，並且除了已經配置好的硬碟外又接了其他硬碟，請檢查硬碟順序是不是正確的。在安裝 RAID 時，硬碟編號可能是 hdd、hde 和 hdf，但是重啟後它們的編號可能變成了 hda、hdb 和 hdc。請相應地調整你的內核參數。這種情況經常發生。

### Error: "kernel: ataX.00: revalidation failed"

如果你突然（在重啟、修改 BIOS 設置後）遇到類似錯誤信息：

    Feb  9 08:15:46 hostserver kernel: ata8.00: revalidation failed (errno=-5)

這並不意味著設備已經損壞。儘管你可能會在網上看到一些講內核崩潰的連結指向最壞的結果，但總而言之，並不是內核崩潰。可能你不知怎麼的在 BIOS 裡或內核參數裡修改了 APIC 或 ACPI 設置。把它改回來就好了。通常關閉 APIC 和/或 ACPI 就好了。

### 磁碟陣列以只讀模式啟動

當由 md 啟動磁碟陣列時，超級塊將被改寫，數據同步可能已經開始了。要以只讀模式啟動，可以向內核模塊 `md_mod` 傳遞參數 `start_ro`。設置了這個參數以後，新的磁碟陣列進入 'auto-ro' 模式，該模式停止了所有內部讀寫操作（更新超級塊、再同步、數據恢復），並且會在第一個寫入請求到來時自動切換至 'rw' （讀寫）模式。

注意：在第一個寫入請求到來前使用 `mdadm --readonly` 命令可以將陣列設置為真正的 'ro' （只讀）模式，還可以用 `mdadm --readwrite` 命令直接開始再同步而不用等待寫入請求。

要在啟動時設置該參數，在內核啟動參數中添加 `md_mod.start_ro=1`。

或者通過內核模塊#使用 /etc/modprobe.d/中的文件在模塊加載時傳遞該參數，也可以直接從 `/sys/` 傳遞：

    # echo 1 > /sys/module/md_mod/parameters/start_ro

### 在損壞或缺失磁碟的情況下恢復 RAID

當磁碟陣列中的一個驅動器由於任何原因損壞時，也可能會發生上述錯誤。如果在缺失一塊硬碟的情況下你仍需要強制啟動磁碟陣列，輸入以下命令（根據實際修改）：

    # mdadm --manage /dev/md0 --run

現在你應該可以用類似下面的命令來掛載它（如果在 fstab 裡有它的話）：

    # mount /dev/md0

現在磁碟陣列應該已經工作並且可以使用，但仍舊是缺一塊盤的狀態。因此需要按照上文 #準備設備所述再添加一個磁碟分區，然後就可以將新磁碟分區加入到磁碟陣列中：

    # mdadm --manage --add /dev/md0 /dev/sdd1

如果輸入：

    # cat /proc/mdstat

你就能看到磁碟陣列已經激活並正在重建。

你可能還需要更新你的配置文件（參閱：#更新配置文件）。

## 基準測試

用於 RAID 基準測試的工具有很多種。不同 RAID 最顯著的不同是多個線程在讀取 RAID 卷時的速度提升程度。

bonnie++包 測試對一個或多個資料庫類型文件的讀寫，以及對小文件的創建、讀取、刪除，這樣可以模擬 Squid、INN 和 Maildir format e-mail 等程序的文件讀寫。其附帶的 ZCAV 程序可以測試硬碟不同區域的性能，且不用向硬碟寫入任何數據。

不應該使用 hdparm 來對 RAID 進行基準測試，因為它多次返回的結果會非常不一致。

## 參考資料

- Linux kernel RAID documentation
- Linux Software RAID (thomas-krenn.com)
- Linux RAID wiki entry in The Linux kernel archives
- How Bitmaps Work
- Chapter 19. Managing RAID of Red Hat Enterprise Linux 9 documentation
- Linux-RAID FAQ on the Linux documentation project
- BAARF(Archive.org) including Why should I not use RAID 5?(Archive.org) by Art S. Kagel
- Introduction to RAID, Nested-RAID: RAID-5 and RAID-6 Based Configurations, Intro to Nested-RAID: RAID-01 and RAID-10, and Nested-RAID: The Triple Lindy in Linux Magazine
- HowTo: Speed Up Linux Software Raid Building And Re-syncing
- Wikipedia:Non-RAID drive architectures

郵件列表

- Kernel Linux-Raid mailing list

mdadm

- mdadm source code
- Software RAID on Linux with mdadm in Linux Magazine
- Wikipedia - mdadm

論壇帖子

- Raid Performance Improvements with bitmaps
- GRUB and GRUB2
- Can't install grub2 on software RAID
- Use RAID metadata 1.2 in boot and root partition

分類：​

- 存儲虛擬化

隱藏分類：​

- 包含損壞章節連結的頁面

RAID
新增話題