mdadm (multiple disk administration) is the standard Linux utility for creating, managing, and monitoring software RAID arrays using the kernel md driver.

Table of Contents#

  1. Overview
  2. RAID Levels
  3. Installation
  4. Creating a RAID Array
  5. Persistent Configuration
  6. Monitoring and Alerting
  7. Disk Failure and Recovery
  8. Write-Intent Bitmap
  9. Array Management
  10. Troubleshooting
  11. See Also
  12. Sources

1. Overview#

mdadm manages Linux software RAID arrays built on the kernel's md (multiple devices) driver. It supports RAID levels 0, 1, 4, 5, 6, and 10, plus linear (JBOD) and multipath configurations. Software RAID via mdadm:

  • Runs on any hardware without a dedicated RAID controller
  • Stores metadata (superblock) on each member device for portability
  • Supports hot-spare disks for automatic failure recovery
  • Integrates with the initramfs for booting from RAID arrays
  • Provides email alerting on disk failures via the monitoring daemon

Components#

ComponentDescription
md driverKernel module that implements the RAID logic
mdadmUserspace tool for array creation, management, and monitoring
SuperblockMetadata stored on each device describing the array layout (version 1.2 is default)
Chunk sizeUnit of data striping (default 512 KiB)
BitmapWrite-intent log that speeds up resync after unclean shutdown

2. RAID Levels#

LevelTypeMin DisksRedundancyUsable CapacityBest For
0Stripe2NoneN x diskTemporary/scratch data
1Mirror21 disk can fail1 x diskBoot drives, OS mirrors
5Stripe + parity31 disk can fail(N-1) x diskGeneral purpose
6Stripe + double parity42 disks can fail(N-2) x diskLarge arrays, high reliability
10Stripe of mirrors41 per mirror pairN/2 x diskDatabases, high IOPS
LinearConcatenation2NoneN x diskSimple capacity aggregation

3. Installation#

# Debian/Ubuntu
sudo apt update && sudo apt install -y mdadm

# RHEL/CentOS/Rocky
sudo dnf install -y mdadm

# Arch Linux
sudo pacman -S mdadm

4. Creating a RAID Array#

Step 1: Identify and Prepare Disks#

# List available disks
lsblk

# Ensure target disks have no existing partitions or data
sudo wipefs -a /dev/sda /dev/sdb /dev/sdc

Step 2: Create the Array#

RAID 1 (2-disk mirror):

sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sda /dev/sdb

RAID 5 (3 disks + optional spare):

sudo mdadm --create /dev/md0 --level=5 --raid-devices=3 \
  --spare-devices=1 /dev/sda /dev/sdb /dev/sdc /dev/sdd

RAID 6 (4 disks):

sudo mdadm --create /dev/md0 --level=6 --raid-devices=4 \
  /dev/sda /dev/sdb /dev/sdc /dev/sdd

RAID 10 (4 disks, near layout):

sudo mdadm --create /dev/md0 --level=10 --raid-devices=4 \
  --layout=n2 /dev/sda /dev/sdb /dev/sdc /dev/sdd

Step 3: Create Filesystem and Mount#

# Format the array
sudo mkfs.ext4 /dev/md0

# Or with XFS
sudo mkfs.xfs /dev/md0

# Create mount point and mount
sudo mkdir -p /mnt/raid
sudo mount /dev/md0 /mnt/raid

Step 4: Verify#

sudo mdadm --detail /dev/md0
cat /proc/mdstat

5. Persistent Configuration#

Without a persistent configuration file, the array may not assemble automatically on reboot.

Saving the mdadm Configuration#

# Scan for arrays and write to config
sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf

# On RHEL-based systems
sudo mdadm --detail --scan | sudo tee -a /etc/mdadm.conf

Updating initramfs#

The initramfs must include the mdadm configuration to assemble arrays at boot:

# Debian/Ubuntu
sudo update-initramfs -u

# RHEL/CentOS
sudo dracut --force

# Arch Linux
sudo mkinitcpio -P

Adding to fstab#

# Get the UUID of the array
sudo blkid /dev/md0

# Add to /etc/fstab
echo 'UUID=<array-uuid>  /mnt/raid  ext4  defaults  0 2' | sudo tee -a /etc/fstab

Always use UUID rather than /dev/md0 in fstab, since device names can change across reboots.

6. Monitoring and Alerting#

mdadm Monitor Daemon#

mdadm includes a monitoring mode that watches arrays and sends email alerts on events (disk failure, rebuild start, rebuild complete, spare activation).

# Test monitoring (sends a test alert, runs once)
sudo mdadm --monitor --scan --test --oneshot

# Run the monitor daemon
sudo mdadm --monitor --scan --daemonise --mail=admin@example.com --delay=300

Systemd Service#

Most distributions ship an mdadm monitoring service:

# Enable the monitoring service
sudo systemctl enable --now mdmonitor

# Check status
sudo systemctl status mdmonitor

Configuration for Email Alerts#

# /etc/mdadm/mdadm.conf (or /etc/mdadm.conf)
MAILADDR admin@example.com

Ensure a working MTA (postfix, msmtp, or similar) is configured on the system.

Checking Array Status#

# Quick status of all arrays
cat /proc/mdstat

# Detailed status of a specific array
sudo mdadm --detail /dev/md0

# Check for degraded arrays
sudo mdadm --detail /dev/md0 | grep -i state

Scheduled Scrubbing#

Regular data scrubbing detects and corrects silent corruption:

# Trigger a check (non-destructive)
echo check | sudo tee /sys/block/md0/md/sync_action

# Monitor progress
cat /proc/mdstat

# View mismatch count after check
cat /sys/block/md0/md/mismatch_cnt

Automate via cron or systemd timer:

# /etc/cron.d/mdadm-scrub
0 2 1 * * root echo check > /sys/block/md0/md/sync_action

7. Disk Failure and Recovery#

Detecting a Failed Disk#

# Check array status
sudo mdadm --detail /dev/md0

# Look for [UU_] pattern indicating a missing/failed disk
cat /proc/mdstat

Output example for a degraded RAID 5:

md0 : active raid5 sdc[2] sdb[1] sda[0](F)
      2093056 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/2] [_UU]

Removing a Failed Disk#

# Mark the disk as failed (if not already)
sudo mdadm /dev/md0 --fail /dev/sda

# Remove the failed disk from the array
sudo mdadm /dev/md0 --remove /dev/sda

Adding a Replacement Disk#

# Wipe the replacement disk
sudo wipefs -a /dev/sde

# Add the new disk to the array
sudo mdadm /dev/md0 --add /dev/sde

If there was no hot spare, adding a new disk triggers an automatic rebuild.

Monitoring the Rebuild#

# Watch rebuild progress
watch cat /proc/mdstat

# Detailed rebuild info
sudo mdadm --detail /dev/md0

Rebuild time depends on array size, disk speed, and I/O load. Estimated time is shown in /proc/mdstat:

[=>...................]  recovery = 12.5% (131072/1046528) finish=5.2min speed=29127K/sec

Controlling Rebuild Speed#

# Set minimum rebuild speed (KB/s)
echo 50000 | sudo tee /sys/block/md0/md/sync_speed_min

# Set maximum rebuild speed (KB/s) to limit impact on production I/O
echo 200000 | sudo tee /sys/block/md0/md/sync_speed_max

Using Hot Spares#

A hot spare is automatically activated when a disk fails:

# Add a spare during array creation
sudo mdadm --create /dev/md0 --level=5 --raid-devices=3 \
  --spare-devices=1 /dev/sda /dev/sdb /dev/sdc /dev/sdd

# Add a spare to an existing array
sudo mdadm /dev/md0 --add /dev/sdd
# If the array is not degraded, the disk becomes a spare automatically

Growing an Array#

# Add a disk and grow from 3 to 4 active RAID 5 devices
sudo mdadm /dev/md0 --add /dev/sde
sudo mdadm --grow /dev/md0 --raid-devices=4

# After reshape completes, expand the filesystem
sudo resize2fs /dev/md0    # ext4
sudo xfs_growfs /mnt/raid  # XFS

8. Write-Intent Bitmap#

A write-intent bitmap tracks which regions of the array have pending writes. After an unclean shutdown, only dirty regions need resync instead of the entire array, dramatically reducing recovery time.

Adding a Bitmap#

# Add an internal bitmap (stored on array member devices)
sudo mdadm --grow /dev/md0 --bitmap=internal

# Add an external bitmap file (for SSDs where write amplification matters)
sudo mdadm --grow /dev/md0 --bitmap=/path/to/bitmap

Removing a Bitmap#

sudo mdadm --grow /dev/md0 --bitmap=none

Bitmap Trade-offs#

AspectWithout BitmapWith Bitmap
Clean shutdown recoveryFull resyncNo resync needed
Unclean shutdown recoveryFull resync (hours)Partial resync (seconds to minutes)
Write performanceNormal~5-10% overhead
Recommended forDisposable/scratch arraysProduction arrays

9. Array Management#

Viewing Array Details#

# Summary of all arrays
cat /proc/mdstat

# Detailed info for one array
sudo mdadm --detail /dev/md0

# Examine a member device
sudo mdadm --examine /dev/sda

Stopping and Reassembling#

# Stop an array
sudo umount /mnt/raid
sudo mdadm --stop /dev/md0

# Assemble from config
sudo mdadm --assemble --scan

# Assemble manually
sudo mdadm --assemble /dev/md0 /dev/sda /dev/sdb /dev/sdc

Deleting an Array#

# Stop the array
sudo umount /mnt/raid
sudo mdadm --stop /dev/md0

# Zero the superblock on all member devices
sudo mdadm --zero-superblock /dev/sda /dev/sdb /dev/sdc

# Remove from mdadm.conf
sudo vi /etc/mdadm/mdadm.conf

# Update initramfs
sudo update-initramfs -u

Renaming an Array#

# Assemble with a new name
sudo mdadm --stop /dev/md0
sudo mdadm --assemble /dev/md1 /dev/sda /dev/sdb /dev/sdc --update=name

10. Troubleshooting#

IssueCauseSolution
Array not assembled on bootMissing or outdated mdadm.confRun mdadm --detail --scan >> /etc/mdadm/mdadm.conf and update-initramfs -u
Array in degraded stateDisk failed or was removedReplace the failed disk (see recovery steps above); add a hot spare for future protection
mdadm: /dev/md0 assembled from 2 drives - not enough to startToo few surviving members for the RAID levelUse --force to start a degraded array: mdadm --assemble --force /dev/md0 /dev/sda /dev/sdb
Rebuild never completesI/O contention or very large disksIncrease sync_speed_min; reduce workload during rebuild; consider bitmap to avoid future full resyncs
mismatch_cnt nonzero after scrubSilent bit-rot or swap/temp file writes on RAID 5/6Small counts on RAID 5/6 from swap files are normal; persistent large counts indicate hardware issues
/dev/md0 device number changes across rebootsDevice enumeration order changedUse UUID= in fstab and ensure mdadm.conf has UUID= entries from --detail --scan
Cannot stop array: "device or resource busy"Filesystem still mounted or process using the arrayRun umount /mnt/raid; check with lsof /mnt/raid or fuser -m /dev/md0
RAID 5/6 write hole after power loss (no bitmap)Parity not consistentAdd a write-intent bitmap to prevent future occurrences; check data integrity manually

See Also#

Sources#