When working with RAID0 arrays, one common challenge is redistributing data between disks while maintaining array integrity. The scenario involves:
- Initial 2-disk RAID0 array (/dev/sda and /dev/sdb)
- Adding a new disk (/dev/sdc)
- Moving data from /dev/sdb to /dev/sdc
- Finally removing /dev/sdb from the array
Here's the step-by-step approach using mdadm:
# 1. First, stop the array
sudo mdadm --stop /dev/md0
# 2. Create a new RAID0 array with the original and new disk
sudo mdadm --create /dev/md0 --level=0 --raid-devices=2 /dev/sda /dev/sdc
# 3. Mount the temporary array
sudo mount /dev/md0 /mnt/temp
# 4. Mount the original array read-only
sudo mdadm --assemble --readonly /dev/md1 /dev/sda /dev/sdb
sudo mount -o ro /dev/md1 /mnt/original
# 5. Copy data between arrays
sudo rsync -avxHAX --progress /mnt/original/ /mnt/temp/
For a lower-level approach without filesystem awareness:
# 1. Create partition tables identical to source disk
sudo sfdisk -d /dev/sdb | sudo sfdisk /dev/sdc
# 2. Copy data block by block
sudo dd if=/dev/sdb of=/dev/sdc bs=4M status=progress
# 3. Verify the copy
sudo cmp /dev/sdb /dev/sdc
After successful data migration:
# Stop all arrays
sudo mdadm --stop /dev/md0
sudo mdadm --stop /dev/md1
# Recreate the array with desired disks
sudo mdadm --create /dev/md0 --level=0 --raid-devices=2 /dev/sda /dev/sdc
# Update mdadm.conf
sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf
sudo update-initramfs -u
- Always maintain complete backups before performing such operations
- For production systems, consider using LVM or more flexible RAID levels
- Monitor the array after reconstruction:
cat /proc/mdstat
- Performance may vary during the migration process
RAID0 (striping) doesn't support disk removal by design - that's why you're forced to consider manual data migration. The striping nature means your data is split evenly across all member disks without redundancy.
Here's the step-by-step method I've successfully used in production environments:
# 1. Create single-disk RAID0 on the new drive
mdadm --create /dev/md1 --level=0 --raid-devices=1 /dev/sdc
# 2. Format and mount the new array
mkfs.ext4 /dev/md1
mount /dev/md1 /mnt/newdisk
# 3. Copy data from old array
rsync -aHAXv /mount/point/of/original/raid/ /mnt/newdisk/
# 4. Prepare new RAID0 configuration
mdadm --stop /dev/md0
mdadm --create /dev/md0 --level=0 --raid-devices=2 /dev/sda /dev/sdc
For more flexibility in future operations, consider setting up LVM on top of your RAID:
# Create physical volumes
pvcreate /dev/sda /dev/sdc
# Create volume group
vgcreate raid_vg /dev/sda /dev/sdc
# Create logical volume
lvcreate -n raid_lv -l 100%FREE raid_vg
When performing the migration:
- The
dd
approach will be faster but requires array downtime - The
rsync
method allows for partial migration while the array is live - Consider using
ionice
to reduce impact on production workloads
After migration completes:
# Check array consistency
mdadm --detail /dev/md0
# Verify filesystem integrity
fsck -f /dev/md0
# Compare checksums (example with important_dir)
cd /original/mount && find important_dir -type f -exec md5sum {} + | sort > /tmp/orig.md5
cd /new/mount && find important_dir -type f -exec md5sum {} + | sort > /tmp/new.md5
diff /tmp/orig.md5 /tmp/new.md5
For repeated operations, here's a basic migration script:
#!/bin/bash
OLD_DISK="/dev/sdb"
NEW_DISK="/dev/sdc"
MOUNT_POINT="/data"
# Safety checks
[ -b "$OLD_DISK" ] || { echo "Old disk missing"; exit 1; }
[ -b "$NEW_DISK" ] || { echo "New disk missing"; exit 1; }
echo "Starting migration..."
mdadm --create /dev/md1 --level=0 --raid-devices=1 $NEW_DISK
mkfs.ext4 /dev/md1
mkdir -p /mnt/migration_target
mount /dev/md1 /mnt/migration_target
rsync -aHAXv $MOUNT_POINT/ /mnt/migration_target/
umount /mnt/migration_target
echo "Rebuilding array..."
mdadm --stop /dev/md0
mdadm --create /dev/md0 --level=0 --raid-devices=2 /dev/sda $NEW_DISK
mount /dev/md0 $MOUNT_POINT
echo "Migration complete!"