DEV Community

iapilgrim
iapilgrim

Posted on

🧠 Migrating BSC Testnet Data to a New Disk (KVM + Docker)

Running blockchain nodes at scale quickly turns into a storage management problem.
In this guide, I’ll walk through a real-world migration of a BSC testnet dataset (~243GB) to a new disk β€” without breaking the node β€” and share key lessons learned.

πŸ“Š Initial Situation

Inside the VM:

/dev/vdb1 β†’ /node-data (6.3T disk, almost full)
Enter fullscreen mode Exit fullscreen mode

Breakdown:

  • Mainnet: ~5.8TB
  • Testnet: ~243GB

Problem:

Disk usage: 100%
Free space: ~41GB ⚠️
Enter fullscreen mode Exit fullscreen mode

πŸ‘‰ Risk: node crash, DB corruption, sync failure


🎯 Goal

  • Move testnet data to a new disk
  • Keep mainnet untouched
  • Avoid complex Docker changes
  • Minimize downtime

πŸ—οΈ Architecture Before

vdb (6.3T)
└── /node-data
    β”œβ”€β”€ mainnet (~5.8T)
    └── testnet (~243G)
Enter fullscreen mode Exit fullscreen mode

πŸš€ Architecture After

vdb β†’ mainnet
vdc β†’ testnet

/bsc-testnet β†’ real mount
/node-data/testnet β†’ bind mount β†’ /bsc-testnet
Enter fullscreen mode Exit fullscreen mode

Docker still uses:

/node-data/testnet:/bsc/node
Enter fullscreen mode Exit fullscreen mode

πŸ‘‰ No container config change needed.


⚑ Step-by-Step Migration

1️⃣ Attach new disk (on host)

qemu-img create -f qcow2 /path/bsc-testnet.qcow2 400G

virsh attach-disk bsc \
  /path/bsc-testnet.qcow2 \
  vdc \
  --targetbus virtio \
  --subdriver qcow2 \
  --persistent
Enter fullscreen mode Exit fullscreen mode

2️⃣ Prepare disk (inside VM)

Skip partitioning (simpler):

mkfs.ext4 /dev/vdc
mkdir /bsc-testnet
mount /dev/vdc /bsc-testnet
Enter fullscreen mode Exit fullscreen mode

3️⃣ Copy data

rsync -avh /node-data/testnet/ /bsc-testnet/
Enter fullscreen mode Exit fullscreen mode

4️⃣ Switch using bind mount (no Docker change)

docker stop testnet

mv /node-data/testnet /node-data/testnet-old
mkdir /node-data/testnet

mount --bind /bsc-testnet /node-data/testnet

docker start testnet
Enter fullscreen mode Exit fullscreen mode

5️⃣ Cleanup (after verification)

rm -rf /node-data/testnet-old
Enter fullscreen mode Exit fullscreen mode

6️⃣ Make persistent

Edit /etc/fstab:

UUID=<vdc-uuid> /bsc-testnet ext4 defaults 0 0
/bsc-testnet /node-data/testnet none bind 0 0
Enter fullscreen mode Exit fullscreen mode

Test:

mount -a
Enter fullscreen mode Exit fullscreen mode

πŸ”₯ Key Lessons Learned

1️⃣ You don’t need to touch Docker

Instead of:

  • editing volumes
  • recreating containers

πŸ‘‰ Just move the filesystem underneath

This is safer and faster.


2️⃣ Bind mounts are extremely powerful

/node-data/testnet β†’ /bsc-testnet
Enter fullscreen mode Exit fullscreen mode

Acts like:

  • transparent redirect
  • zero config change
  • instant rollback

3️⃣ β€œtarget is busy” = you are inside the directory

Classic mistake:

umount /node-data/testnet
β†’ target is busy
Enter fullscreen mode Exit fullscreen mode

Cause:

cwd = /node-data/testnet
Enter fullscreen mode Exit fullscreen mode

Fix:

cd /
Enter fullscreen mode Exit fullscreen mode

4️⃣ Duplicate mounts can happen easily

Running mount --bind multiple times creates stacked mounts.

Check with:

mount | grep testnet
findmnt /node-data/testnet
Enter fullscreen mode Exit fullscreen mode

Fix:

umount /node-data/testnet (repeat until gone)
Enter fullscreen mode Exit fullscreen mode

5️⃣ Never unmount while container is running

Even if it β€œworks”:

  • DB writes can fail
  • corruption risk
  • node may resync from scratch

πŸ‘‰ Always:

docker stop β†’ umount β†’ remount β†’ start
Enter fullscreen mode Exit fullscreen mode

6️⃣ Partitioning is optional

For dedicated disks:

mkfs.ext4 /dev/vdc
Enter fullscreen mode Exit fullscreen mode

is simpler than:

fdisk β†’ /dev/vdc1
Enter fullscreen mode Exit fullscreen mode

7️⃣ Blockchain nodes will ALWAYS outgrow your disk

After migration:

mainnet still ~92% full
Enter fullscreen mode Exit fullscreen mode

πŸ‘‰ This is temporary relief.

You must plan:

  • disk expansion (qemu-img resize)
  • or data rebalancing

πŸ“ˆ Results

After migration:

  • Freed ~243GB on main disk
  • Isolated IO between mainnet/testnet
  • No Docker reconfiguration
  • Minimal downtime (~1–2 minutes)

🧠 Final Takeaway

The key mindset shift:

Don’t move applications β€” move the filesystem underneath them.

This approach:

  • reduces risk
  • simplifies operations
  • scales better for large datasets (TBs)

πŸš€ What’s Next

For production-grade setups:

  • Separate disks per chain
  • Use virsh blockcopy for live migration
  • Implement storage balancing strategy across NVMe pools

Top comments (0)