Efficient live full disk backup

Overview

Live full disk backups are preferred in many scenarios, despite their space requirements. The following outlines an efficient method to do that using libvirt's APIs. This method involves concepts: the notion of backing chains, QCOW2 overlays, and a special operation called "active block-commit", which allows live-merging an overlay disk image into its backing file.

At a high-level, this is the approach to take a live ful disk backup: Assuming a guest with a single disk image, create a temporary live QCOW2 overlay (commonly called as "external snapshot") to track the live guest writes. Then backup the original disk image while the guest (live QEMU) keeps writing to the temporary overlay. Finally, perform the "active block-commit" opertion to live-merge the temporary overlay disk contents into the original image — i.e. the backing file — and "pivot" the live QEMU process to point to it.

The below assumes you're using at least these versions (preferably much newer): QEMU 2.1 and libvirt-1.2.9.

Detailed procedure

  1. Start with a guest with a single disk image, base.raw, which is where the live QEMU is pointing at, and recording the guest writes:

    base.raw (live QEMU)
    
  2. List the current block device(s) in use:

    $ virsh domblklist vm1
    Target     Source
    ------------------------------------------------
    vda        /var/lib/libvirt/images/base.raw
    
  3. Create the live "external disk snapshot" (or more correctly, "an overlay"):

    $ virsh snapshot-create-as --domain vm1 overlay1 \
        --diskspec vda,file=/var/lib/libvirt/images/overlay1.qcow2 \
        --disk-only
    

    The disk image chain looks as follows:

    base.raw <-- overlay1.qcow2 (live QEMU)
    

Note

Above, if you have QEMU guest agent installed in your virtual machine, use the --quiesce option with virsh snapshot-create-as [...] to ensure you have a consistent disk state.

Optionally, you can also supply the --no-metadata option to virsh snapshot-create-as to tell libvirt not track the snapshot metadata. Otherwise, when you decide to merge snapshot overlays, you have to explicitly clean the libvirt metadata using virsh snapshot-delete vm1 --metadata [name|--current].

  1. Now, take a backup the orignal image, base.raw, to a different location using cp or rsync:

    $ cp /var/lib/libvirt/images/base.raw
        /export/backups/copy1_base.raw
    
    # Or:
    
    $ rsync -avhW --progress /var/lib/libvirt/images/base.raw \
        /export/backups/copy1_base.raw
    
  2. Enumerate the current block device(s) in use, again. Notice that the current disk image in use is the above-created overlay, overlay1.qcow2:

    $ virsh domblklist vm1
    Target     Source
    ------------------------------------------------
    vda        vda,file=/var/lib/libvirt/images/overlay1.qcow2
    
  3. Once the backup of the original image completes, now perform the "active block-commit" to live-merge the contents of overlay1.qcow2 into base.raw and pivot the live QEMU back to the original:

    $ virsh blockcommit vm1 vda --active --verbose --pivot
    
  4. After the above operation completes, again list the current block device(s) in use. And notice that the live QEMU is now writing to the original base image:

    $ virsh domblklist vm1
    Target     Source
    ------------------------------------------------
    vda        /var/lib/libvirt/images/base.raw
    

The final updated disk image "chain" will be a single consolidated disk:

[base.raw] (live QEMU)

Now you can safely discard the overlay image, overlay1.qcow2 — it is no longer valid; and its contents are now fully merged into the base image.