Last updated: 2026-08-20

Linux Software RAID with mdadm

Category: Redundant StorageTechnologies: mdadm, MD kernel driver, RAID 0/1/5/6/10, write-intent bitmaps

mdadm (Multiple Devices Admin) manages Linux software RAID through the kernel's MD driver. It combines two or more physical disks or partitions into virtual block devices (/dev/md0, /dev/md1, …), supporting RAID 0, 1, 5, 6, and 10 for redundancy and performance without dedicated hardware.

RAID improves availability but is not a substitute for backups. See the backup and disaster recovery guide for proper backup strategy.

RAID levels

LevelMin disksFault toleranceCapacityReadWriteBest for
RAID 02NoneN × diskExcellentExcellentScratch, cache, temp data
RAID 121 disk (N−1)1 × diskGoodModerateBoot/OS volumes
RAID 531 disk(N−1) × diskGoodModerateRead-heavy general storage
RAID 642 disks(N−2) × diskGoodModerate-slowLarge arrays, >4 TB disks
RAID 1041 per mirror pairN/2 × diskExcellentExcellentDatabases, high-IOPS

RAID 10 layouts

The --layout option controls how mirror copies are distributed:

Creating arrays

# RAID 0
mdadm --create /dev/md0 --level=0 --raid-devices=2 /dev/sdb1 /dev/sdc1

# RAID 1
mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb1 /dev/sdc1

# RAID 5
mdadm --create /dev/md0 --level=5 --raid-devices=3 /dev/sdb1 /dev/sdc1 /dev/sdd1

# RAID 6
mdadm --create /dev/md0 --level=6 --raid-devices=4 /dev/sd[bcde]1

# RAID 10 with far layout
mdadm --create /dev/md0 --level=10 --layout=f2 --raid-devices=4 /dev/sd[bcde]1

# With hot spare
mdadm --create /dev/md0 --level=5 --raid-devices=3 --spare-devices=1 /dev/sd[bcde]1

# With custom chunk size (default 512 KiB)
mdadm --create /dev/md0 --level=5 --raid-devices=3 --chunk=64 /dev/sd[bcd]1

# With write-intent bitmap
mdadm --create /dev/md0 --level=5 --raid-devices=3 --bitmap=internal /dev/sd[bcd]1

Examining arrays

# Detailed view of an active array
mdadm --detail /dev/md0

# Brief view (suitable for mdadm.conf)
mdadm --detail --brief /dev/md0

# Scan all arrays and output ARRAY lines
mdadm --detail --scan

# Examine a component device's superblock
mdadm --examine /dev/sdb1

# Kernel view of active arrays
cat /proc/mdstat

Example /proc/mdstat output:

Personalities : [raid1] [raid5] [raid6] [raid10]
md0 : active raid5 sda1[0] sdb1[1] sdc1[2]
      209584128 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/3] [UUU]
      bitmap: 0/1 pages [0KB], 65536KB chunk
unused devices: <none>

The [UUU] field shows device health: U = up, _ = down/failed.

Monitoring

# Start monitor daemon (scans mdadm.conf)
mdadm --monitor --scan --daemonize

# With email alerts
mdadm --monitor --scan --mail=admin@example.com --daemonize

# Send a test alert
mdadm --monitor --scan --test

# Via systemd
systemctl enable --now mdmonitor.service

For proactive disk health monitoring beyond mdadm's event alerts, see the SMART monitoring guide.

mdadm.conf

The configuration file (/etc/mdadm.conf or /etc/mdadm/mdadm.conf on Debian) tells the initramfs which arrays to assemble at boot. Generate it after every array change:

# Generate ARRAY lines from active arrays
mdadm --detail --scan >> /etc/mdadm.conf

# Update initramfs so boot can find the array
update-initramfs -u     # Debian/Ubuntu
dracut -f               # RHEL/Fedora

A typical file:

MAILADDR root
ARRAY /dev/md0 metadata=1.2 UUID=12345678:12345678:12345678:12345678 name=host:0

Adding, removing, and replacing disks

# Mark a disk as failed
mdadm /dev/md0 --fail /dev/sdb1

# Remove the failed disk
mdadm /dev/md0 --remove /dev/sdb1

# Add a new (or replacement) disk
mdadm /dev/md0 --add /dev/sdb1

# Re-add a previously removed disk
mdadm /dev/md0 --re-add /dev/sdb1

Complete disk replacement procedure

# 1. Identify the failed disk
mdadm --detail /dev/md0
cat /proc/mdstat
smartctl -a /dev/sdb | grep -i serial

# 2. Fail and remove
mdadm /dev/md0 --fail /dev/sdb1
mdadm /dev/md0 --remove /dev/sdb1

# 3. Physically replace the disk

# 4. Copy partition table from a healthy disk
sfdisk -d /dev/sdc | sfdisk /dev/sdb
# For GPT:
sgdisk -R /dev/sdb /dev/sdc
sgdisk -G /dev/sdb          # randomize the disk GUID

# 5. Add the new partition to the array
mdadm /dev/md0 --add /dev/sdb1

# 6. Watch the rebuild
watch cat /proc/mdstat

Growing arrays

# Add a disk, then grow to include it (RAID 5: 3 → 4 disks)
mdadm /dev/md0 --add /dev/sdd1
mdadm --grow /dev/md0 --raid-devices=4 --backup-file=/tmp/grow_backup

# RAID level migration (0 → 5)
mdadm --grow /dev/md0 --level=5 --raid-devices=3

# Change chunk size
mdadm --grow /dev/md0 --chunk=128
Backup file for reshape safety

Reshaping (adding disks, changing level, changing chunk) is a long operation that rewrites the entire array. The --backup-file is required when growing without spare devices, shrinking, or changing RAID level/layout. It provides a safety net for critical metadata during reshape. The array remains usable during reshape but with a performance penalty.

Stopping and assembling

# Stop an array
mdadm --stop /dev/md0

# Assemble from explicit devices
mdadm --assemble /dev/md0 /dev/sdb1 /dev/sdc1 /dev/sdd1

# Assemble all arrays from mdadm.conf
mdadm --assemble --scan

# Force assembly of a dirty/degraded array
mdadm --assemble --scan --force

Superblock versions

VersionMetadata locationNotes
0.9064K-128K from end of deviceLegacy. Max 28 devices, 2 TB per device (kernel < 3.1) / 4 TB (kernel >= 3.1). Required by GRUB Legacy / LILO.
1.08K-12K from end of deviceRequired by Syslinux. Data starts at offset 0.
1.1At byte 0 (start of device)Rarely used in production.
1.2 (default)4K from start, data at ~1 MiBDefault for all modern systems. 1 MiB alignment optimal for 4Kn drives.
# Specify at creation time
mdadm --create /dev/md0 --level=1 --raid-devices=2 --metadata=1.0 /dev/sd[bc]1

# Zero out a superblock before reusing a disk
mdadm --zero-superblock /dev/sdb1

RAID 5/6 write hole

The write hole is a fundamental timing problem in parity RAID: updating a stripe requires writing both data and parity blocks, and these are separate writes. If power is lost between them, data and parity become inconsistent. On a degraded array, inconsistent parity cannot be recalculated, leading to silent data corruption during rebuild.

Mitigations

# Write-intent bitmap (tracks dirty chunks for fast recovery)
mdadm --grow /dev/md0 --bitmap=internal

# Write journal (dedicated journal device, RAID 4/5/6)
mdadm --create /dev/md0 --level=5 --raid-devices=3 \
  --write-journal=/dev/sdj1 /dev/sd[abc]1

# Consistency scrub
echo check > /sys/block/md0/md/sync_action
cat /sys/block/md0/md/mismatch_cnt
echo repair > /sys/block/md0/md/sync_action

Write-intent bitmaps

Bitmap typePerformance impactRecovery speed
internalSignificant random-write penalty (bitmap updated on every write)Fast, only dirty chunks rebuilt
external (on SSD)Minimal if on fast deviceFast
noneBest write performanceFull rebuild
# Add internal bitmap
mdadm --grow /dev/md0 --bitmap=internal

# Add external bitmap on a separate file
mdadm --grow /dev/md0 --bitmap=/raidbitmap.bin

# Remove bitmap
mdadm --grow /dev/md0 --bitmap=none

Partitions vs whole disks

ApproachProsCons
PartitionsTolerates size variation between replacement disks; allows multiple arrays per diskSlightly more setup
Whole disksSimpler; no partition table overheadReplacement disk must be at least as large; no partition table warnings

Recommendation: use partitions slightly smaller than full disk capacity (e.g., leave a 100 MB margin) to accommodate size variations between nominally identical disks from different manufacturers.

Many setups layer LVM on top of mdadm arrays for flexible volume management and snapshots. For TRIM support on RAID arrays, see the TRIM and discard guide.

Degraded boot

If the root filesystem is on RAID and a disk is missing at boot, the initramfs may refuse to start a dirty degraded array. Force it from the emergency shell:

# In initramfs emergency shell
mdadm --assemble --scan --force
mdadm --run /dev/md0

Kernel parameter to allow dirty degraded starts:

md-mod.start_dirty_degraded=1

Command quick reference

OperationCommand
Create arraymdadm --create /dev/md0 --level=5 --raid-devices=3 /dev/sd[bcd]1
Detailmdadm --detail /dev/md0
Statuscat /proc/mdstat
Fail diskmdadm /dev/md0 --fail /dev/sdb1
Remove diskmdadm /dev/md0 --remove /dev/sdb1
Add diskmdadm /dev/md0 --add /dev/sdb1
Grow arraymdadm --grow /dev/md0 --raid-devices=4 --backup-file=/tmp/bak
Stopmdadm --stop /dev/md0
Assemblemdadm --assemble --scan
Scrubecho check > /sys/block/md0/md/sync_action
Zero superblockmdadm --zero-superblock /dev/sdb1
Generate configmdadm --detail --scan >> /etc/mdadm.conf

Sources & references

  1. mdadm(8) — Linux manual page — primary man page for mdadm, documents all modes (create, assemble, grow, monitor) and RAID level specifications
  2. RAID arrays — Linux Kernel documentation — official kernel admin guide for MD RAID, covers boot-time assembly, superblock formats, and degraded boot
  3. RAID driver API — Linux Kernel documentation — kernel driver documentation for MD RAID, including RAID 4/5/6 cache and Partial Parity Log features
  4. dm-raid — Linux Kernel documentation — documents the device-mapper RAID target that bridges DM to MD, supporting LVM RAID
  5. RAID 4/5/6 cache (write hole mitigation) — official kernel documentation explaining the write hole problem and how write-through/write-back cache mitigates it

Frequently asked questions

How do you replace a failed disk in an mdadm RAID array?

Fail the disk with `mdadm /dev/md0 --fail`, remove it with `--remove`, copy the partition table from a healthy disk, then add the replacement with `--add`. The array rebuilds automatically; monitor with `watch cat /proc/mdstat`.

What is the RAID 5/6 write hole?

Updating a stripe requires separate writes for data and parity. If power is lost between them, data and parity become inconsistent. On a degraded array this causes silent corruption during rebuild. Write-intent bitmaps and a write journal mitigate it.

What does [UUU] mean in /proc/mdstat?

The bracket field shows per-device health. `U` means the device is up and `_` means it is down or failed. `[UUU]` indicates all three devices in a three-disk array are healthy.

How do you grow an mdadm array?

Add a disk with `mdadm --add`, then run `mdadm --grow` with the new `--raid-devices` count. Use `--backup-file` when reshaping without spares, shrinking, or changing RAID level. The array stays usable during reshape but with a performance penalty.

What is a write-intent bitmap in mdadm?

It tracks dirty chunks so only changed regions rebuild after a crash. Internal bitmaps have a random-write penalty; external bitmaps on SSD have minimal impact; no bitmap gives best write performance but requires a full rebuild.

Which mdadm superblock version should I use?

Version 1.2 is the default for modern systems, with 1 MiB alignment optimal for 4Kn drives. Use 0.90 only for GRUB Legacy or LILO, and 1.0 if Syslinux is required.

How do you boot from a degraded RAID array?

In the initramfs emergency shell run `mdadm --assemble --scan --force` and `mdadm --run /dev/md0`. To allow dirty degraded starts automatically, add the kernel parameter `md-mod.start_dirty_degraded=1`.