Setting up, monitoring, and recovering software RAID on Linux
A single disk is always just a matter of time. RAID with mdadm spreads data redundantly across multiple disks, so a disk failure does not immediately take the server down but can be fixed while the system keeps running.
Table of Contents
- 1. Why software RAID with mdadm is still relevant
- 2. RAID levels at a glance: 0, 1, 5, 6, 10
- 3. Creating a RAID array with mdadm
- 4. Making the array configuration persistent
- 5. Checking status and monitoring arrays
- 6. Detecting and replacing a failed disk
- 7. Email notifications for array problems
- 8. Performance aspects and common pitfalls
- 9. RAID levels in direct comparison
- 10. Summary
- 11. FAQ
1. Why software RAID with mdadm is still relevant
RAID (Redundant Array of Independent Disks) spreads data across multiple physical disks to gain fault tolerance, performance, or both at once. On Linux, mdadm (Multiple Disk Administration) handles this entirely in software, with no need for an expensive hardware RAID controller. Especially on virtual servers and in cloud environments, where hardware RAID is not available anyway, mdadm is the only practical option for establishing local data redundancy.
A RAID array with mdadm does not replace a backup, that is a common misunderstanding. RAID only protects against the failure of individual disks, not against accidental deletion, ransomware, or an application bug that writes incorrect data. Anyone running production databases or media directories combines RAID with a separate backup strategy, RAID provides availability during normal operation, the backup provides recoverability after a logical error.
2. RAID levels at a glance: 0, 1, 5, 6, 10
Choosing the right RAID level determines how much usable storage remains and how many disk failures the array can survive. RAID 0 spreads data across multiple disks with no redundancy at all and only maximizes speed, if one disk fails, all data is lost. RAID 1 mirrors data identically onto two disks, losing half the raw capacity, but survives the failure of either disk without data loss.
RAID 5 spreads data and parity information across at least three disks and survives the failure of exactly one disk, though with larger arrays holding many terabytes per disk, the recovery risk during a rebuild becomes noticeable. RAID 6 extends this principle with a second parity block and survives two simultaneous failures, at the cost of more capacity. RAID 10 combines mirroring and striping, offering the best combination of performance and fault tolerance, but requires at least four disks and half the raw capacity as overhead.
3. Creating a RAID array with mdadm
Creating an array with mdadm --create needs three pieces of information: the name of the resulting device (usually /dev/md0), the desired RAID level, and the list of participating disks. All participating disks should be identically sized, otherwise mdadm aligns to the smallest disk and wastes capacity on the larger devices.
# Create a RAID 1 mirror from two identical disks
sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb /dev/sdc
# Create a RAID 5 array from four disks (one disk worth of parity)
sudo mdadm --create /dev/md1 --level=5 --raid-devices=4 \
/dev/sdd /dev/sde /dev/sdf /dev/sdg
# Watch the initial sync progress
cat /proc/mdstat
Right after creation, mdadm starts an initial synchronization in the background, mirroring every bit for RAID 1, or computing parity data for RAID 5 and 6. This process can take several hours on large disks, but the array is already usable during that time, albeit with reduced performance. Progress can be followed at any time via /proc/mdstat.
4. Making the array configuration persistent
An array freshly created with mdadm --create is initially only known to the running system, after a reboot it would otherwise have to be reassembled manually. The solution is an entry in /etc/mdadm/mdadm.conf that describes the array signature and instructs mdadm during boot to automatically detect and assemble it.
# Persist the array definition so mdadm assembles it automatically on boot
sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf
# Rebuild the initramfs so the boot process knows about the array
sudo update-initramfs -u
# /etc/fstab entry for the resulting RAID device
UUID=7b2e9f10-4a3c-4d5e-8f61-2b9c0e1a3d44 /var/lib/mysql ext4 defaults,noatime 0 2
After changing mdadm.conf, the initramfs must be rebuilt, because the earliest phase of the boot process may already need the RAID array, for example when the root filesystem itself sits on the array. Anyone who forgets this step will find, after the next reboot, an array that is not assembled automatically even though the configuration file looks correct.
5. Checking status and monitoring arrays
The fastest way to see the state of every array at a glance is cat /proc/mdstat, which lists every line with level, participating disks, and sync status. For details on a single array, such as which disk is currently marked as a spare or how far a rebuild has progressed, mdadm --detail provides the full picture.
# Current status of every assembled array
cat /proc/mdstat
# Detailed view: disk states, spare devices, sync progress
sudo mdadm --detail /dev/md0
# Trigger a full data scrub (detects silent bit-rot)
echo check | sudo tee /sys/block/md0/md/sync_action
# Read the scrub result afterwards
cat /sys/block/md0/md/mismatch_cnt
A regular data scrub, triggered via sync_action, compares the mirrored copies for RAID 1 or data and parity for RAID 5/6 and uncovers so called bit rot, silent bit errors that would otherwise only show up at the next disk failure. Most distributions already set up this scrub as a monthly cron job, a look into /etc/cron.d/mdadm shows whether that is the case.
6. Detecting and replacing a failed disk
If a disk in a redundant array fails, mdstat reports the array as degraded, it keeps running, but without redundancy. Replacement happens in three steps: the failed disk is explicitly marked as failed, then removed from the array, and only then is the new disk added. mdadm starts the rebuild automatically as soon as the new disk is detected.
# Mark a disk as failed and remove it from the array
sudo mdadm /dev/md0 --fail /dev/sdc
sudo mdadm /dev/md0 --remove /dev/sdc
# Add the replacement disk (must be the same size or larger)
sudo mdadm /dev/md0 --add /dev/sdh
# Watch the rebuild progress
watch cat /proc/mdstat
During the rebuild the array is especially vulnerable, with RAID 5 for example there is no redundancy left during this phase, a second disk failure would lead to complete data loss. For exactly this reason, RAID 6 or RAID 10 are considered a much safer choice for larger arrays with many terabytes per disk, since rebuild times on large disks can now take many hours.
7. Email notifications for array problems
A degraded array that nobody notices is, in practice, almost as dangerous as having no RAID at all. mdadm's own monitoring daemon mdmonitor (or mdadm --monitor) watches all configured arrays in the background and automatically sends an email on events such as a disk failure, a completed rebuild, or a detected error.
Configuration happens through the MAILADDR variable in mdadm.conf, a working local mail delivery setup (for example Postfix relaying to an external SMTP server) is a prerequisite. Without this step, a disk failure can go unnoticed for weeks until a second failure in the same array leads to complete data loss.
8. Performance aspects and common pitfalls
RAID 5 and RAID 6 carry a noticeable write overhead, the so called write hole, or the need to recompute parity on every write. For database workloads with many small, random writes, RAID 10 is therefore usually the better choice, even though it costs more raw capacity. RAID 0 should only be used in production for data whose loss is uncritical, such as pure cache directories.
# /etc/mdadm/mdadm.conf: enable email alerts for array events
MAILADDR ops@mironsoft.de
MAILFROM raid-monitor@mironsoft.de
# Restart the monitoring daemon after changing the config
sudo systemctl restart mdmonitor
sudo systemctl status mdmonitor
A common pitfall: mdadm identifies arrays based on metadata stored at the beginning or end of each participating disk, if a disk is reused for a different array without clearing the old metadata, mdadm can produce confusing assembly errors on the next boot. mdadm --zero-superblock cleanly removes these leftovers before a disk is adopted into a new array.
9. RAID levels in direct comparison
Every RAID level is a trade off between capacity, performance, and fault tolerance. The following overview shows when which level makes sense with mdadm.
| Requirement | Unsuitable level | Recommended level with mdadm | Reason |
|---|---|---|---|
| Performance only, uncritical data | RAID 5 (unnecessary overhead) | RAID 0 | Full speed, no redundancy needed |
| Two disks, high reliability | RAID 0 (no protection) | RAID 1 | Simple mirroring, survives one failure |
| Database with many random writes | RAID 5 (write overhead) | RAID 10 | Best write performance with redundancy |
| Large archive, many disks | RAID 5 (rebuild risk) | RAID 6 | Survives two simultaneous failures |
| Securing the root filesystem | No RAID | RAID 1 on system disks | Server keeps booting despite a disk failure |
In practice, RAID 10 dominates for databases, and RAID 6 for large media archives with less frequent writes. RAID 5 has lost some appeal on modern, large disks because of the long rebuild times, but remains a solid compromise for smaller arrays with three to four disks.
Mironsoft
Linux server administration, storage redundancy and fault tolerance
Servers that shrug off a disk failure?
We plan and set up RAID arrays with mdadm for your production servers, including monitoring, email alerting, and a clean separation between RAID redundancy and a real backup strategy.
RAID planning
Level selection matched to the workload: database, media archive, or root filesystem
Monitoring and alerting
mdmonitor setup with email notifications on disk failures
Emergency recovery
Replacing failed disks while the system stays online, with no downtime
10. Summary
RAID with mdadm protects Linux servers against the failure of individual disks, but does not replace a backup. Choosing the right RAID level, from RAID 1 for simple mirroring to RAID 10 for database workloads, determines capacity, performance, and how many simultaneous failures the array can survive.
An array without monitoring is only half the protection: only the combination of /proc/mdstat, a regular data scrub, and email notifications on events turns mdadm into a reliable tool for production use.
RAID with mdadm: The essentials at a glance
Level choice
RAID 1 for simple mirroring, RAID 10 for databases, RAID 6 for large archives with many disks.
Setup
mdadm --create builds the array, an entry in mdadm.conf plus an initramfs update makes it persistent.
Monitoring
/proc/mdstat for an overview, mdadm --detail for details, a regular data scrub against bit rot.
No backup substitute
RAID protects against disk failure, not against deletion mistakes or ransomware. A backup remains mandatory as well.