Под капотом · Виртуализация · Бэкапы

Бэкап через временный снимок

Пользователь идёт старой схемой: снимок, копирование, слияние обратно. Для этого он вводит несколько команд:

Команда
virsh domfsfreeze vm1
virsh snapshot-create-as vm1 tmp --disk-only --atomic --no-metadata
virsh domfsthaw vm1
cp --sparse=always /var/lib/libvirt/images/vm1.qcow2 /backup/vm1-copy.qcow2
virsh blockcommit vm1 vda --active --pivot
libvirt API virDomainFSFreeze · SnapshotCreateXML · virDomainBlockCommit(ACTIVE) · BlockJobAbort(PIVOT) QMP block-commit (active)

После выполнения команд ВМ возвращается на исходный файл:

  • Команда domfsfreeze даёт согласованный срез диска;
  • Команда snapshot-create-as создаёт оверлей и переключает на него ВМ;
  • Команда domfsthaw возвращает запись, диск продолжает жить в оверлее;
  • Команда cp копирует base, пока тот доступен только для чтения;
  • Команда blockcommit вливает оверлей обратно и переключает ВМ на base.
  • пользователь 1. Пользователь вводит команду заморозки ФС
    virDomainFSFreeze()

    Нужен гостевой агент. Без него снимок будет «как при сбое питания».

  • libvirt 2. Демон делает временный снимок диска
    virDomainSnapshotCreateXML(xml,
      VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY)

    Внешний инструмент получит неизменяемый файл - читать его безопасно.

  • гость 3. Гость снова работает
    virDomainFSThaw()

    Запись идёт уже в оверлей, а не в копируемый файл.

  • диск / RAM 4. Внешний инструмент копирует данные
    cp/rsync/агент читает base
    # здесь проходит основное время

    Копия появляется именно сейчас: сам снимок копией не является.

  • libvirt 5. Демон вливает оверлей обратно
    virDomainBlockCommit(VIR_DOMAIN_BLOCK_COMMIT_ACTIVE)

    Active commit втягивает в базу и активный слой, и промежуточные. Это внутренность одной CLI-команды blockcommit --pivot: она сама ждёт BLOCK_JOB_READY и вызывает BlockJobAbort(PIVOT).

  • QEMU 6. QEMU сообщает о готовности
    {"event":"BLOCK_JOB_READY"}
    → block-job-complete

    До complete job остаётся активным - здесь ещё можно отменить.

  • libvirt 7. Демон закрывает job и переключает диск
    virDomainBlockJobAbort(
      VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT)

    Без флага PIVOT active commit просто отменяется, и ВМ остаётся на временном оверлее.

  • пользователь 8. Если что-то прервалось
    ВМ осталась на временном оверлее
    → ручная правка определения

    Именно поэтому прямая схема бэкапа предпочтительнее: определение ВМ не меняется.