Configure Linux software RAID arrays with mdadm to improve disk performance and protect against drive failures. Learn to create RAID 0, 1, 5, 6, and 10 configurations with automatic monitoring and management.
Prerequisites
- Multiple unused storage devices (minimum 2 drives)
- Root or sudo access
- Basic understanding of Linux disk management
What this solves
Software RAID with mdadm lets you combine multiple physical drives into a single logical volume for better performance, redundancy, or both. This tutorial shows you how to create different RAID levels, configure automatic assembly on boot, and monitor array health for production systems.
Install mdadm and prepare storage devices
Install mdadm package
The mdadm utility manages software RAID arrays on Linux systems.
sudo apt update
sudo apt install -y mdadm
Identify available storage devices
Check which drives are available for RAID configuration. Look for unused devices without existing partitions.
lsblk
fdisk -l
This tutorial assumes you have drives at /dev/sdb, /dev/sdc, /dev/sdd, and /dev/sde. Adjust paths based on your system.
Wipe existing data from drives
Clear any existing partition tables or filesystem signatures from the drives you'll use for RAID.
sudo wipefs -af /dev/sdb /dev/sdc /dev/sdd /dev/sde
sudo dd if=/dev/zero of=/dev/sdb bs=1M count=10
sudo dd if=/dev/zero of=/dev/sdc bs=1M count=10
sudo dd if=/dev/zero of=/dev/sdd bs=1M count=10
sudo dd if=/dev/zero of=/dev/sde bs=1M count=10
Create RAID arrays with mdadm
Create RAID 0 array for maximum performance
RAID 0 stripes data across drives for best performance but provides no redundancy. One drive failure destroys the entire array.
sudo mdadm --create --verbose /dev/md0 --level=0 --raid-devices=2 /dev/sdb /dev/sdc
Format the array with a filesystem:
sudo mkfs.ext4 /dev/md0
sudo mkdir /mnt/raid0
sudo mount /dev/md0 /mnt/raid0
Create RAID 1 array for data mirroring
RAID 1 mirrors data across drives, providing complete redundancy. You can lose one drive without data loss.
sudo mdadm --create --verbose /dev/md1 --level=1 --raid-devices=2 /dev/sdd /dev/sde
Format and mount the mirrored array:
sudo mkfs.ext4 /dev/md1
sudo mkdir /mnt/raid1
sudo mount /dev/md1 /mnt/raid1
Create RAID 5 array for balanced performance and redundancy
RAID 5 requires at least 3 drives and can survive the loss of one drive while maintaining data integrity.
sudo mdadm --create --verbose /dev/md5 --level=5 --raid-devices=3 /dev/sdb /dev/sdc /dev/sdd
Format the RAID 5 array:
sudo mkfs.ext4 /dev/md5
sudo mkdir /mnt/raid5
sudo mount /dev/md5 /mnt/raid5
Create RAID 6 array for dual drive fault tolerance
RAID 6 requires at least 4 drives and can survive the failure of any two drives simultaneously.
sudo mdadm --create --verbose /dev/md6 --level=6 --raid-devices=4 /dev/sdb /dev/sdc /dev/sdd /dev/sde
Format and mount the RAID 6 array:
sudo mkfs.ext4 /dev/md6
sudo mkdir /mnt/raid6
sudo mount /dev/md6 /mnt/raid6
Create RAID 10 array for maximum performance and redundancy
RAID 10 combines mirroring and striping, requiring at least 4 drives. It provides excellent performance and can survive multiple drive failures.
sudo mdadm --create --verbose /dev/md10 --level=10 --raid-devices=4 /dev/sdb /dev/sdc /dev/sdd /dev/sde
Format the RAID 10 array:
sudo mkfs.ext4 /dev/md10
sudo mkdir /mnt/raid10
sudo mount /dev/md10 /mnt/raid10
Configure automatic RAID assembly and monitoring
Save RAID configuration to mdadm.conf
Generate the configuration file so arrays are automatically assembled at boot time.
sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf
Update the initramfs to include RAID configuration:
sudo update-initramfs -u
Configure permanent mount points
Add RAID arrays to /etc/fstab for automatic mounting at boot.
echo '/dev/md1 /mnt/raid1 ext4 defaults,nofail 0 2' | sudo tee -a /etc/fstab
echo '/dev/md10 /mnt/raid10 ext4 defaults,nofail 0 2' | sudo tee -a /etc/fstab
The nofail option prevents boot failures if a RAID array has issues.
Enable mdadm monitoring service
Configure email alerts for RAID events like drive failures or degraded arrays.
MAILADDR admin@example.com
Start and enable the monitoring daemon:
sudo systemctl enable --now mdmonitor
sudo systemctl status mdmonitor
Set up automated health checks
Configure monthly scrubbing to detect and correct errors proactively.
#!/bin/bash
for array in $(cat /proc/mdstat | grep -o 'md[0-9]*'); do
echo check > /sys/block/${array}/md/sync_action
done
Make the script executable:
sudo chmod +x /etc/cron.monthly/raid-check
Monitor RAID health and manage failed drives
Check RAID array status
Monitor the health and performance of your RAID arrays with these commands.
cat /proc/mdstat
sudo mdadm --detail /dev/md1
sudo mdadm --detail /dev/md10
Look for State : clean and all drives showing as active sync status.
Simulate and handle drive failures
Mark a drive as failed to test your monitoring and replacement procedures.
sudo mdadm --manage /dev/md1 --fail /dev/sde
Remove the failed drive from the array:
sudo mdadm --manage /dev/md1 --remove /dev/sde
Add a replacement drive to rebuild the array:
sudo mdadm --manage /dev/md1 --add /dev/sdf
Monitor rebuild progress
Track the progress of array rebuilds and data synchronization.
watch -n 5 'cat /proc/mdstat'
sudo mdadm --detail /dev/md1 | grep -E "State|Rebuild Status"
Rebuilds can take several hours depending on drive size and system load.
Set up SMART monitoring integration
Combine RAID monitoring with disk health checks using smartmontools.
sudo apt install -y smartmontools
Configure SMART monitoring for early drive failure detection:
/dev/sdb -a -m admin@example.com
/dev/sdc -a -m admin@example.com
/dev/sdd -a -m admin@example.com
/dev/sde -a -m admin@example.com
sudo systemctl enable --now smartd
Verify your setup
Confirm your RAID arrays are working correctly and will survive reboots.
cat /proc/mdstat
sudo mdadm --detail --scan
sudo mdadm --detail /dev/md1
df -h /mnt/raid1 /mnt/raid10
sudo systemctl status mdmonitor
sudo systemctl status smartd
Test write performance on different RAID levels:
sudo dd if=/dev/zero of=/mnt/raid1/testfile bs=1M count=1000 oflag=direct
sudo dd if=/dev/zero of=/mnt/raid10/testfile bs=1M count=1000 oflag=direct
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Array fails to assemble at boot | Missing mdadm.conf or initramfs not updated | sudo mdadm --detail --scan >> /etc/mdadm/mdadm.conf and rebuild initramfs |
| Drive shows as "spare" instead of "active" | Array size mismatch or partition alignment | Use --force flag or repartition drives with identical sizes |
| Poor write performance on RAID 5/6 | No write cache or small chunk size | Enable write cache with mdadm --readwrite /dev/mdX and tune chunk size |
| Email alerts not working | No mail system configured | Install and configure system logging or use external monitoring |
| RAID array marked as dirty after crash | Unclean shutdown during write operations | sudo mdadm --assemble --force /dev/mdX then run filesystem check |
Next steps
- Set up Linux storage monitoring with smartmontools and automated health alerts for proactive drive monitoring
- Configure backup compression and deduplication with BorgBackup and rsync for optimal storage efficiency
- Monitor Linux system resources with performance alerts and automated responses
- Configure RAID performance monitoring with Prometheus and Grafana dashboards
- Set up automated RAID drive replacement workflows with Ansible
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Production-quality RAID setup script with mdadm
# Supports Ubuntu, Debian, AlmaLinux, Rocky Linux, CentOS, RHEL, Oracle Linux, Fedora
# Colors for output
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
readonly NC='\033[0m'
# Global variables
RAID_LEVEL=""
DEVICES=()
MOUNT_POINT=""
PKG_MGR=""
PKG_INSTALL=""
MDADM_CONF="/etc/mdadm/mdadm.conf"
MD_DEVICE=""
# Cleanup on error
cleanup() {
local exit_code=$?
if [[ $exit_code -ne 0 && -n "${MD_DEVICE:-}" ]]; then
echo -e "${YELLOW}[CLEANUP] Attempting to stop RAID array ${MD_DEVICE}...${NC}"
mdadm --stop "${MD_DEVICE}" 2>/dev/null || true
wipefs -af "${MD_DEVICE}" 2>/dev/null || true
fi
exit $exit_code
}
trap cleanup ERR
usage() {
cat << EOF
Usage: $0 <raid_level> <mount_point> <device1> <device2> [device3] [device4]
RAID Levels:
0 - Striping (min 2 devices, no redundancy)
1 - Mirroring (exactly 2 devices)
5 - Parity (min 3 devices, 1 drive fault tolerance)
6 - Double parity (min 4 devices, 2 drive fault tolerance)
10 - Stripe+Mirror (exactly 4 devices)
Examples:
$0 1 /mnt/raid1 /dev/sdb /dev/sdc
$0 5 /mnt/raid5 /dev/sdb /dev/sdc /dev/sdd
$0 10 /mnt/raid10 /dev/sdb /dev/sdc /dev/sdd /dev/sde
EOF
exit 1
}
log() {
echo -e "${GREEN}$*${NC}"
}
warn() {
echo -e "${YELLOW}WARNING: $*${NC}" >&2
}
error() {
echo -e "${RED}ERROR: $*${NC}" >&2
exit 1
}
detect_distro() {
if [[ ! -f /etc/os-release ]]; then
error "Cannot detect distribution: /etc/os-release not found"
fi
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
if ! command -v dnf &>/dev/null && command -v yum &>/dev/null; then
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
fi
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
;;
*)
error "Unsupported distribution: $ID"
;;
esac
# Handle different mdadm.conf locations
if [[ "$ID" == "debian" || "$ID" == "ubuntu" ]]; then
MDADM_CONF="/etc/mdadm/mdadm.conf"
else
MDADM_CONF="/etc/mdadm.conf"
fi
}
check_prerequisites() {
echo "[1/8] Checking prerequisites..."
if [[ $EUID -ne 0 ]]; then
error "This script must be run as root or with sudo"
fi
# Validate RAID level and device count
local device_count=${#DEVICES[@]}
case "$RAID_LEVEL" in
0)
[[ $device_count -ge 2 ]] || error "RAID 0 requires at least 2 devices"
MD_DEVICE="/dev/md0"
;;
1)
[[ $device_count -eq 2 ]] || error "RAID 1 requires exactly 2 devices"
MD_DEVICE="/dev/md1"
;;
5)
[[ $device_count -ge 3 ]] || error "RAID 5 requires at least 3 devices"
MD_DEVICE="/dev/md5"
;;
6)
[[ $device_count -ge 4 ]] || error "RAID 6 requires at least 4 devices"
MD_DEVICE="/dev/md6"
;;
10)
[[ $device_count -eq 4 ]] || error "RAID 10 requires exactly 4 devices"
MD_DEVICE="/dev/md10"
;;
*)
error "Invalid RAID level: $RAID_LEVEL"
;;
esac
# Check if devices exist
for device in "${DEVICES[@]}"; do
[[ -b "$device" ]] || error "Device $device does not exist or is not a block device"
done
# Check if mount point parent exists
local parent_dir
parent_dir=$(dirname "$MOUNT_POINT")
[[ -d "$parent_dir" ]] || error "Parent directory $parent_dir does not exist"
}
install_mdadm() {
echo "[2/8] Installing mdadm..."
if command -v mdadm &>/dev/null; then
log "mdadm already installed"
return
fi
case "$PKG_MGR" in
apt)
apt update
$PKG_INSTALL mdadm
;;
dnf|yum)
$PKG_INSTALL mdadm
;;
esac
log "mdadm installed successfully"
}
prepare_devices() {
echo "[3/8] Preparing storage devices..."
warn "This will PERMANENTLY DELETE ALL DATA on: ${DEVICES[*]}"
echo "Press Ctrl+C within 10 seconds to abort..."
sleep 10
for device in "${DEVICES[@]}"; do
log "Wiping $device..."
wipefs -af "$device"
dd if=/dev/zero of="$device" bs=1M count=10 status=none
done
log "All devices prepared"
}
create_raid_array() {
echo "[4/8] Creating RAID $RAID_LEVEL array..."
local device_count=${#DEVICES[@]}
mdadm --create --verbose "$MD_DEVICE" \
--level="$RAID_LEVEL" \
--raid-devices="$device_count" \
"${DEVICES[@]}"
# Wait for array to be ready
while [[ ! -b "$MD_DEVICE" ]]; do
sleep 1
done
log "RAID array $MD_DEVICE created successfully"
}
format_and_mount() {
echo "[5/8] Formatting and mounting RAID array..."
# Format with ext4
mkfs.ext4 -F "$MD_DEVICE"
# Create mount point
mkdir -p "$MOUNT_POINT"
chmod 755 "$MOUNT_POINT"
# Mount the array
mount "$MD_DEVICE" "$MOUNT_POINT"
log "Array formatted and mounted at $MOUNT_POINT"
}
configure_auto_assembly() {
echo "[6/8] Configuring automatic assembly..."
# Ensure mdadm config directory exists
mkdir -p "$(dirname "$MDADM_CONF")"
# Generate mdadm configuration
mdadm --detail --scan >> "$MDADM_CONF"
chmod 644 "$MDADM_CONF"
# Update initramfs/initrd
case "$PKG_MGR" in
apt)
update-initramfs -u
;;
dnf|yum)
dracut --force
;;
esac
log "Auto-assembly configured"
}
configure_persistent_mount() {
echo "[7/8] Configuring persistent mount..."
# Add to fstab
local uuid
uuid=$(blkid -s UUID -o value "$MD_DEVICE")
# Use UUID for more reliable mounting
echo "UUID=$uuid $MOUNT_POINT ext4 defaults,nofail 0 2" >> /etc/fstab
log "Persistent mount configured"
}
enable_monitoring() {
echo "[8/8] Enabling RAID monitoring..."
# Enable mdmonitor service
case "$PKG_MGR" in
apt)
systemctl enable mdmonitor 2>/dev/null || systemctl enable mdadm 2>/dev/null || true
systemctl start mdmonitor 2>/dev/null || systemctl start mdadm 2>/dev/null || true
;;
dnf|yum)
systemctl enable mdmonitor
systemctl start mdmonitor
;;
esac
log "RAID monitoring enabled"
}
verify_installation() {
echo -e "\n${BLUE}=== RAID Array Verification ===${NC}"
# Check array status
log "Array status:"
mdadm --detail "$MD_DEVICE"
echo
log "Mount status:"
df -h "$MOUNT_POINT"
echo
log "RAID configuration:"
cat "$MDADM_CONF"
echo -e "\n${GREEN}RAID $RAID_LEVEL array successfully created and configured!${NC}"
echo -e "Device: ${BLUE}$MD_DEVICE${NC}"
echo -e "Mount point: ${BLUE}$MOUNT_POINT${NC}"
echo -e "Used devices: ${BLUE}${DEVICES[*]}${NC}"
}
main() {
# Parse arguments
[[ $# -ge 4 ]] || usage
RAID_LEVEL="$1"
MOUNT_POINT="$2"
shift 2
DEVICES=("$@")
detect_distro
check_prerequisites
install_mdadm
prepare_devices
create_raid_array
format_and_mount
configure_auto_assembly
configure_persistent_mount
enable_monitoring
verify_installation
}
main "$@"
Review the script before running. Execute with: bash install.sh