[TUTORIAL] Backup RAW image oder ZFS_SEND -> restic

ivenae

Well-Known Member
Feb 11, 2022
200
99
48
42

Proxmox-Backup nach restic: ResticBackup.sh und ResticRestore.sh​

Zwei Bash-Skripte, eine gemeinsame config.cfg, ein restic-Repository auf einer externen Platte. Dedupliziert, verschlüsselt, ohne Umweg zurückspielbar – und einzelne Dateien erreichbar, ohne vorher hunderte Gigabyte auszupacken.

Voraussetzung: bestehende Snapshots​


Das Backupskript legt selbst keine ZFS-Snapshots an. Für ZFS-Volumes - VM-Disks wieLXC-rootfs - nimmt es immer den neuesten vorhandenen Snapshot des Datasets, sowohl für zfs send als auch als Lesequelle für RAW. Fehlt einer, wird die Platte übersprungen,statt ein verschmiertes Image zu schreiben (RAW_REQUIRE_SNAPSHOT). Ist er älter als 24Stunden, gibt es eine Warnung - gesichert wird genau dieser Stand.

Die Aktualität der Sicherung hängt damit am Snapshot-Mechanismus des Hosts: ein Cronjob mit cv4pve-autosnap oder die Snapshots von Proxmox selbst -Hauptsache, kurz vor dem Backuplauf entsteht einer.

Ausnahmen: auf LVM und LVM-thin legt das Skript selbst einen temporären Snapshot an und räumt ihn wieder ab, auf Directory-Storage wird live gelesen, ohne Konsistenzgarantie.

Sicherungsmedium​

  • Ziel wird über die UUID gesucht, nicht über einen festen Pfad; mehrere UUIDs = rotierende Medien
  • Log hält fest, welche Platte lief, und warnt, wenn 30 Läufe lang immer dieselbe steckte
  • nach dem Lauf fstrim, Standby (hdparm -y), unmount

Formate​

  • RAW (Standard): Volume blockweise als Image, aus ZFS- oder temporärem LVM-Snapshot. Jedes Backup steht für sich – keine Kette, Restore in einem Schritt
  • zfs send (optional): pro Platte (ZFS_SEND_DISKS="100:scsi1") oder für alles. Full + Diffs; neues Full bei zu altem Full, fehlender Basis oder zu großem Diff. Spart Lese-I/O auf großen Datenplatten, braucht aber Platz für zwei Generationen – lohnende Kandidaten meldet der Lauf selbst
  • Dateibasiert: LXC-rootfs über ro-Snapshot, LOCAL_DIRS, Maschinenconfigs
  • Ein config-id-Tag klammert alles zusammen, was zu einem Lauf gehört – der Restore nimmt genau diese Platten

Platz​

  • Bedarf wird exakt gerechnet, nicht geschätzt: neues Backup = volle Quellgröße, vorhandenes = Aufschlag in Prozent; bei RAW zählt die echte Belegung
  • reicht es nicht, werden ganze Backup-Tage freigegeben, alt nach neu: ein Full nimmt Diffs, Configs und immer-full-Volumes mit; neuestes Backup einer Gruppe und ZFS_SEND_DISKS bleiben
  • Aufbewahrung über KEEP_DAILY/WEEKLY/MONTHLY plus prune

Integrität und Warnungen​

  • restic liest gespeicherte Chunks nie wieder – ein verrottetes Pack fiele nicht auf. Deshalb rotierendes Zurücklesen: nach RESTIC_CHECK_ROTATE_RUNS Läufen ist das Repo einmal komplett geprüft, Zähler pro Medium
  • Warnungen ohne Abbruch: volle Host-Dateisysteme, lange Uptime, knapper Platz am Ziel
  • Übersicht aller Backups samt Wiederherstellungsgröße am Ende, auch in der Mail

Restore​

  • --list mit Filtern (Maschine, Typ, Name, Lauf), optional mit Größe; --list-disks <VMID> für den Stand einer Maschine
  • Restore nur mit explizitem --target auf eine freie ID – bestehende Maschinen werden nie überschrieben, bewusst ohne Override
  • --machine = letzter Lauf, --date = letzter vor Stichtag, --snap = genau einer; Zielvolumes per pvesm alloc, Diffs ziehen ihr Full mit

Einzelne Dateien​

  • --mount <SNAP-ID>: Repo per FUSE, RAW-Image als ro-Loop-Device mit gemounteten Partitionen (LVM darin wird aktiviert), LXC/LOCAL direkt als Dateibaum. Kein zusätzlicher Plattenplatz
  • --attach-raw <SNAP-ID> --vm <VMID>: für alles, was der Host nicht lesen kann (Windows, Storage Spaces, LUKS mit Schlüssel im Gast) – Image als SCSI-Platte in die laufende VM
  • --rw schiebt einen qcow2-Overlay davor, den qemu-nbd als /dev/nbdN bereitstellt; Schreibvorgänge landen dort und werden verworfen, das Backup bleibt unberührt
  • dieselbe VM geht mit: Windows hält die Kopie wegen doppelter Signatur offline, Rechtsklick auf den Datenträger → "Online" schreibt die neue Signatur in den Overlay
  • Strg+C räumt vollständig auf; nach einem harten Abbruch holt --detach-raw das nach (VM-Config, Loop/nbd, FUSE-Mount, Overlay, Temp) – erkannt wird nur, was die Skripte selbst angelegt haben
Aus einer Stunde Suchen und Auspacken für eine einzelne Datei wird eine Minute.


Installation und Konfiguration​


Abhängigkeiten:
Code:
apt install restic jq pv

Alle drei Dateien nach /usr/local/bin/ kopieren und .txt Endung entfernen.
Code:
chmod +x ResticBackup.sh
chmod +x ResticRestore.sh

UUID der ext. Festplatte herausfinden und in die /usr/local/bin/config.cfg eintragen.
Code:
blkid

Alle auskommentierten Parameter in der Restic Restore entsprechen dem optionalen Default.

Sicherung aller VMs, LXC Container und den optionalen zu sichernden LOCAL_DIRS durchführen:
Code:
./ResticBackup.sh

Sicherung von Maschine 115 durchführen:
Code:
./ResticBackup.sh 115

Restore
Code:
./ResticRestore.sh --help

# z.B.
./ResticRestore.sh --machine 115 --target 9115

Laufzeiten:​


Code:
VM:
600 GB machine storage
300 GB used
5 GB diff per day
Backup-Storage: 930 GB

               | Read I/O VM  | Write I/O Backup | max Backup count |  runtime
               |  500 MB/s    |     100 MB/s     |    on disk       |
------------------------------------------------------------------------------------
VZDump         |  600 GB      |     250 GB *     |                  |    42 min
------------------------------------------------------------------------------------
20-backup-sum  |   12 TB      |       5 TB       |       2 **       |   840 min



RAW first time |  600 GB      |     250 GB *     |                  |    42 min
RAW following  |  600 GB      |       5 GB       |                  |    20 min
------------------------------------------------------------------------------------
20-backup-sum  |   12 TB      |     345 GB       |     > 100 ***    |   422 min



zfs_s 1. full  |  300 GB      |    300 GB *     |                   |    50 min
zfs_s 1. diff  |    5 GB      |      5 GB       |                   |     1 min
zfs_s 2. diff  |   10 GB      |     10 GB       |                   |     2 min
zfs_s 3. diff  |   15 GB      |     15 GB       |                   |   2.5 min
...
zfs_s 9. diff  |   45 GB      |     45 GB       |                   |   7.5 min
zfs_s 2. full  |  300 GB      |    300 GB       |                   |    50 min
zfs_s 10. diff |    5 GB      |      5 GB       |                   |     1 min
...
------------------------------------------------------------------------------------
20-backup-sum  |  1.1 TB      |    1.1 TB       |      13 ****      |   175 min


*   300 GB used storage can compress to approx 250 GB; if you store via zfs_send, further reduction is not possible
**  I you use the prune process of VZdump, which only prune after backup your total number is 2.
    You can increment this to 3 if you use your own prune process, which prune directly before creation
*** (930 - 250)/5 = 137, but you would not conserve 137 dailys,
    so the difference between individual backups eventually become larger than 5 GB
****Initial you can add 17 backups, but worst case would be: 300+40+45+300+5+10+15+20+25+30+35+40+45 = 910 => 13 backups
 

Attachments

Last edited:
Full Backup (mit einer etwas älteren Version, daher etwas andere Bedingungen für notwendigen Puffer)
Code:
[2026-07-09T22:20:17+0200] [INFO] Password file not found, auto-creating: /media/SmartStore/ResticBackup.pw
[2026-07-09T22:20:17+0200] [INFO] Password generated (32 chars, saved with chmod 600)
[2026-07-09T22:20:17+0200] [WARNING] IMPORTANT: Save this password elsewhere, it is needed for restore!
[2026-07-09T22:20:17+0200] [WARNING]   cat '/media/SmartStore/ResticBackup.pw'
[2026-07-09T22:20:17+0200] [INFO] Repo: /media/SmartStore/ResticBackup
[2026-07-09T22:20:17+0200] [INFO] Restic repo not found, auto-initializing: /media/SmartStore/ResticBackup
[2026-07-09T22:20:19+0200] [INFO] Restic repo initialized and ready
[2026-07-09T22:20:20+0200] [INFO] Repo data size before backup: 0 B
[2026-07-09T22:20:20+0200] [INFO] === Starting Proxmox backup ===
[2026-07-09T22:20:21+0200] [INFO] --- VM 100 (vDC01) ---
[2026-07-09T22:20:24+0200] [INFO]   Disk count changed: repo has 0, VM has 4 -> forcing full backup
[2026-07-09T22:20:24+0200] [INFO]   Disk count changed -> Full backup
[2026-07-09T22:20:24+0200] [INFO]   Full backup: efidisk0
[2026-07-09T22:20:25+0200] [INFO]   OK: efidisk0 full (rpool/data/vm-100-disk-0)
[2026-07-09T22:20:26+0200] [INFO]   Disk count changed -> Full backup
[2026-07-09T22:20:26+0200] [INFO]   Full backup: scsi0
[2026-07-09T23:28:06+0200] [INFO]   OK: scsi0 full (rpool/data/vm-100-disk-4)
[2026-07-09T23:28:07+0200] [INFO]   Disk count changed -> Full backup
[2026-07-09T23:28:07+0200] [INFO]   Full backup: scsi1
[2026-07-09T23:40:45+0200] [INFO]   OK: scsi1 full (rpool/data/vm-100-disk-1)
[2026-07-09T23:40:45+0200] [INFO]   Disk count changed -> Full backup
[2026-07-09T23:40:45+0200] [INFO]   Full backup: tpmstate0
[2026-07-09T23:40:47+0200] [INFO]   OK: tpmstate0 full (rpool/data/vm-100-disk-2)
[2026-07-09T23:40:48+0200] [INFO]   OK: config
[2026-07-09T23:40:48+0200] [INFO] No LXC containers found
[2026-07-09T23:40:51+0200] [INFO] Data added this run: 354.4 GiB
[2026-07-09T23:40:51+0200] [INFO] Disk space: 538.6 GiB free of 893.1 GiB (538.6 GiB), need 443.7 GiB (10% + written)
[2026-07-09T23:40:51+0200] [INFO] === Proxmox backup complete ===
[2026-07-09T23:40:51+0200] [INFO] VMs=1 CTs=0 Disks=4 (Full=4 Incr=0) Skipped=0 | Written=354.4 GiB | Errors=0 Warnings=2
[2026-07-09T23:40:51+0200] [INFO] === Retention: forget + prune ===
[2026-07-09T23:40:51+0200] [INFO] Policy: keep-daily=10 keep-weekly=6 keep-monthly=6
[2026-07-09T23:40:51+0200] [INFO] Protecting full backups referenced by kept incrementals
[2026-07-09T23:40:52+0200] [INFO] Nothing to forget
[2026-07-09T23:40:52+0200] [INFO] === Post-backup integrity check ===
[2026-07-09T23:40:52+0200] [INFO] Data written this run: 354.4 GiB
[2026-07-09T23:40:52+0200] [INFO] Checking: 10G (max: 10 GiB)
[2026-07-09T23:41:19+0200] [INFO] Integrity check passed


Diff Backup. Statt 1,5 Stunden benötigt es nur 1 min. Yay.
Code:
Sichere UUID f0876d4c-8a68-4afe-8c3d-a5c6ae8e59dd
[2026-07-13T12:30:01+0200] [INFO] Base: /media/SmartStore
[2026-07-13T12:30:01+0200] [INFO] Repo: /media/SmartStore/ResticBackup
[2026-07-13T12:30:05+0200] [INFO] Repo data size before backup: 354.4 GiB
[2026-07-13T12:30:05+0200] [INFO] === Starting Proxmox backup ===
[2026-07-13T12:30:05+0200] [INFO] === Planungsphase (Full/Diff-Bestimmung) ===
[2026-07-13T12:30:13+0200] [INFO]   Alle Disks differentiell sicherbar -> kein erzwungenes Full
[2026-07-13T12:30:13+0200] [INFO] === Platzpruefung vor Backup ===
[2026-07-13T12:30:13+0200] [INFO]   Diff-/LXC-/LOCAL-Lauf -> Diff-Run/No VM
[2026-07-13T12:30:13+0200] [INFO]   [Diff-Run/No VM] Frei: 538.6 GiB / 893.1 GiB  |  Puffer (5%): 44.7 GiB
[2026-07-13T12:30:13+0200] [INFO]   [Diff-Run/No VM] Genug frei (>= Puffer) -> kein Pruning noetig
[2026-07-13T12:30:14+0200] [INFO] --- VM 100 (vDC01) ---
[2026-07-13T12:30:15+0200] [INFO]   OK: config
[2026-07-13T12:30:16+0200] [INFO]   Config-Snapshot-ID: 48cf4b7e
[2026-07-13T12:30:18+0200] [INFO]   Differential: autodaily260709190002 -> autohourly260713100002
[2026-07-13T12:30:19+0200] [INFO]   OK: efidisk0 diff (rpool/data/vm-100-disk-0)
[2026-07-13T12:30:22+0200] [INFO]   Age: differential is 3 day(s) after full (a9c732da)
[2026-07-13T12:30:23+0200] [INFO]   Differential: autodaily260709190002 -> autohourly260713100002
[2026-07-13T12:30:26+0200] [INFO]   OK: scsi0 diff (rpool/data/vm-100-disk-4)
[2026-07-13T12:30:29+0200] [INFO]   Age: differential is 3 day(s) after full (bec955ba)
[2026-07-13T12:30:30+0200] [INFO]   Differential: autodaily260709190002 -> autohourly260713100002
[2026-07-13T12:30:47+0200] [INFO]   OK: scsi1 diff (rpool/data/vm-100-disk-1)
[2026-07-13T12:30:50+0200] [INFO]   Age: differential is 3 day(s) after full (03834f68)
[2026-07-13T12:30:52+0200] [INFO]   Differential: autodaily260709190002 -> autohourly260713100002
[2026-07-13T12:30:53+0200] [INFO]   OK: tpmstate0 diff (rpool/data/vm-100-disk-2)
[2026-07-13T12:30:56+0200] [INFO]   Age: differential is 3 day(s) after full (6c5b8dfd)
[2026-07-13T12:30:56+0200] [INFO] No LXC containers found
[2026-07-13T12:30:59+0200] [INFO] Data added this run: 1.8 GiB
[2026-07-13T12:30:59+0200] [INFO] Disk space: 536.8 GiB frei von 893.1 GiB (Warnschwelle 10% = 89.3 GiB)
[2026-07-13T12:30:59+0200] [INFO] === Proxmox backup complete ===
[2026-07-13T12:30:59+0200] [INFO] VMs=1 CTs=0 Disks=4 (Full=0 Diff=4) Skipped=0 | Written=1.8 GiB | Errors=0 Warnings=0
[2026-07-13T12:30:59+0200] [INFO] === Retention: forget + prune ===
[2026-07-13T12:30:59+0200] [INFO] Policy: keep-daily=10 keep-weekly=3 keep-monthly=2
[2026-07-13T12:30:59+0200] [INFO] Protecting full backups referenced by kept differentials
[2026-07-13T12:31:00+0200] [INFO] Nothing to forget
[2026-07-13T12:31:00+0200] [INFO] === Post-backup integrity check ===
[2026-07-13T12:31:00+0200] [INFO] Data written this run: 1.8 GiB
[2026-07-13T12:31:00+0200] [INFO] Checking: 2G (max: 10 GiB)
[2026-07-13T12:31:19+0200] [INFO] Integrity check passed
fstrim /media/SmartStore
fstrim: /media/SmartStore: the discard operation is not supported
fstrim not supported
Unmount /media/SmartStore
Setze standby: /dev/sda

/dev/sda:
 issuing standby command


Auch hier: Das Full Backup wurde mit einer alten Version erstellt, daher fehlen noch ein paar Tags und die Größe kann nicht ermittelt werden.
Die Größe der Config-Datei entspricht der Größe aller Datenträger des Diffs + aller Datenträger des zugehörigen Full Backups.
Code:
root:/usr/local/bin# ./ResticRestore.sh --list --size
SNAP ID     Backup Time       TYPE     MACHINE    NAME                      DISK              SIZE  PARENT      CONFIG
ca828acf    2026-07-11 02:32  CONFIG   vm-100     Server                    -            504.33GiB  -           ca828acf
a928b4dc    2026-07-11 02:32  FULL     vm-100     Server                    scsi1        504.33GiB  -           ca828acf
facd9984    2026-07-11 04:12  CONFIG   vm-101     Client                    -             81.48GiB  -           facd9984
0b9e3348    2026-07-11 04:12  FULL     vm-101     Client                    scsi0         81.48GiB  -           facd9984
493e4519    2026-07-11 23:42  CONFIG   vm-100     Server                    -            506.57GiB  -           493e4519
7667631f    2026-07-11 23:42  DIFF     vm-100     Server                    scsi1        506.57GiB  a928b4dc    493e4519
3cadf33d    2026-07-11 23:42  CONFIG   vm-101     Client                    -             82.94GiB  -           3cadf33d
592c8e47    2026-07-11 23:42  DIFF     vm-101     Client                    scsi0         82.94GiB  0b9e3348    3cadf33d
6b6dacc0    2026-07-14 01:00  CONFIG   vm-100     Server                    -            508.04GiB  -           6b6dacc0
5cee0ad5    2026-07-14 01:00  DIFF     vm-100     Server                    scsi1        508.04GiB  a928b4dc    6b6dacc0
cda6558a    2026-07-14 01:01  CONFIG   vm-101     Client                    -             83.08GiB  -           cda6558a
6557ead4    2026-07-14 01:01  DIFF     vm-101     Client                    scsi0         83.08GiB  0b9e3348    cda6558a


root:/usr/local/bin# ./ResticRestore.sh --target 667 --machine 101
Restic Restore V 4.3.6
[01:26:58] [INFO] Machine: vm-101 -> Target: 667
[01:26:58] [INFO] Config snapshot: cda6558a
[01:26:58] [INFO] Restoring backup run config-id=cda6558a
[01:26:58] [INFO] === Restoring VM 101 -> 667 ===
repository 622c9c8a opened (version 2, compression level auto)
[0:01] 100.00%  28 / 28 index files loaded
restoring snapshot cda6558a of [/vm-101.conf] at 2026-07-14 01:01:23.907287838 +0200 CEST by root to /tmp/restic-restore-cfg-3733521
Summary: Restored 1 files/dirs (581 B) in 0:00
[01:27:01] [INFO]   Config: /etc/pve/qemu-server/667.conf
[01:27:01] [INFO] Restoring disks ...
[01:27:12] [INFO]   scsi0: Full (0b9e3348, 81.48GiB) + Differential (6557ead4, 1.60GiB)
scsi0-full: 81.5GiB 0:19:17 [72.1MiB/s] [================================================================================================================================================================>] 100%
scsi0-diff: 1.60GiB 0:00:24 [67.8MiB/s] [================================================================================================================================================================>] 100%
[01:46:57] [INFO]   OK: scsi0 (full + differential)
[01:46:57] [INFO] === VM 667 restore complete ===
[01:46:57] [INFO] Start with: qm start 667
 
Last edited:
  • Like
Reactions: Johannes S
Cooles Projekt, sieht echt durchdacht aus. restic check verifiziert dir nur die restic-Chunks, ob der zfs-send-Stream danach auch sauber per zfs receive wieder zurückkommt, sagt dir das nicht. Ich würd regelmäßig echt mal einen Test-Restore in ein Scratch-Dataset fahren, gerade wegen der Diff-Ketten. Eine fehlende oder kaputte Full-Basis reißt dir sonst alle Diffs mit, und das merkst du dann zum blödesten Zeitpunkt.

Warum restic statt PBS? Chunk-Dedup über alles statt ~0% zwischen den Fulls, Incrementals per Dirty-Bitmap, verify/GC hättest du geschenkt. Oder gehts dir gezielt um die eine portable USB-Platte, die danach in den Standby geht? Das kann PBS halt nicht.
 
Exakt – Ich betreibe das hauptsächliche Backup noch lokal auf Platte, weil extrem schnell, extrem billig.
Das reduziert die Schreibleistung auch in der Praxis auf ca. 10% ggü. vma.zstd sofern man bis zu 15 Diff-Backups je Fuil-Backup macht.

Es gibt keine "Diff-Ketten". Es handelt sich um ein differentielles Backup, kein inkrementelles.
Jedes Backup ist entweder ein Full, oder die Differenz zum letzten Full Backup. Mehr als zwei Iterationen werden für den Restore daher nicht benötigt.
Ich habe jetzt gut 10 Restores auf verschiedenen Geräten getestet. Es läuft wirklich gut.

Zum Thema Restore-Tests: Damit haben auch Veeam Nutzer ihre Erfahrung gemacht. Und auch mit PBS und VMA/VZDump kommt man um Restore-Tests nicht herum.

EDIT: Alternativer RAW Modus hinzugefügt.

  • RAW benötigt am wenigsten Platz auf dem Zieldatenträger, da es hervorragend dedupliziert wird
  • RAW erzeugt ausschießlich full Backups
  • RAW spart Schreib I/O ggü. VZDump und somit i.d.R. auch Zeit
  • RAW spart keine Lese I/O ggü. VZDump

  • zfs_send benötigt erheblich weniger Lese und Schreib I/O
  • Ggü. VZDump insbesondere bei diffs weniger Zeitbedarf.
  • Bei full Backups nur dann Zeitersparnis, wenn der Backup-Datenträger schnell oder die CPU langsam ist

Ich bin nach wie vor großer Fan von zfs_send, weil es auch riesige Maschinen, die früher 4 Stunden zur VZdump Sicherung benötigt haben nun in 5 min gesichert sind.
Mich überzeugt aber das RAW-Konzept dort, wo ich notorisch zu kleine Backup-Festplatten eingesetzt habe. Da habe ich mit vzdump immer nur 3 Backups behalten, und das auch nur, weil ich mir das Pruning so gebastelt habe, dass alte Backups unmittelbar vor dem sichern bei Platzmangel gelöscht werden. Der normale VZDump Prune Prozess kann das nicht. Der löscht nach dem Backup – damit passen bei einer VM Größe von 250 GB nur 2 Backups auf den Zieldatenträger.
Nach Beobachtungen der letzten Tage gefällt mir RAW immer besser ggü. zfs_send. Insbesondere, weil es das Platzproblem nochmals erheblich besser löst. Ich kann auf einer einzigen, normal großen Festplatte eine monatelange Backup Historie aufbauen.

In einem speziellen Fall ist die VM in den letzten Jahren stark gewachsen und hat nun 600 GB belegten Speicher (angefangen hatten wir mit 250 GB).
Damals bekamen wir gut eine Woche Backups auf den 930 GB Sicherungsdatenträger, der dann wöchentlich gewechselt wurde.
Durch den Datenwachtum innerhalb der letzten 5 Jahre wuchs das Backup-Abbild nun auf > 460 GB.
Das führte nun dazu, dass das letzte Backup gelöscht werden musste, bevor ein neues angelegt werden kann, d.h. es gibt eine kurze Zeit kein einziges Backup mehr auf der aktuellen Backup-Platte. Das ist der absolute Worst-Case, weshalb ich mich dran gemacht habe, den Prozess grundlegend zu überarbeiten, statt einfach eine neue Platte zu kaufen.

Nun bekomme ich dank obigem Tool mehrere Monate Backups auf den Datenträger – statt nur ein einziges.

Wo andere 5.000 € für ein 2x 8 TB NAS ausgeben, liege ich bei 200 € für externe Platten.
 
Last edited:
Nun gibt es Logfiles im direkten Vergleich:
Code:
                 |  size   | time
-----------------------------------
VZDump/Zstd      | 278 GB  | 38 min 
zfs_send full    | 363 GB  | 55 min
zfs_send diff 1. | 3.2 GB  |  1 min
zfs_send diff 3. |  30 GB  |  7 min
RAW first        | 252 GB  | 85 min
RAW second       |   4 GB  | 29 min
Stärken und Schwächen lassen sich hier recht gut ablesen. Kompression bei raw war aber im ersten Lauf max, die wurde später reduziert. Das würde sich dann VZdump vermutlich in Zeit und Speicher ziemlich stark annähern.

VZ-Dump mit ZStd Kompression:
Code:
100: 2026-07-04 01:00:09 INFO: Starting Backup of VM 100 (qemu)
100: 2026-07-04 01:00:09 INFO: status = running
100: 2026-07-04 01:00:09 INFO: VM Name: Win10
100: 2026-07-04 01:00:09 INFO: include disk 'scsi1' 'local-zfs:vm-100-disk-0' 906173M
100: 2026-07-04 01:00:09 INFO: backup mode: snapshot
100: 2026-07-04 01:00:09 INFO: ionice priority: 7
100: 2026-07-04 01:00:09 INFO: snapshots found (not included into backup)
100: 2026-07-04 01:00:09 INFO: creating vzdump archive '/media/SmartStore/vzdump-qemu-100-2026_07_04-01_00_09.vma.zst'
100: 2026-07-04 01:00:09 INFO: issuing guest-agent 'fs-freeze' command
100: 2026-07-04 01:00:10 INFO: starting backup via QMP command
100: 2026-07-04 01:00:10 INFO: issuing guest-agent 'fs-thaw' command
100: 2026-07-04 01:00:12 INFO: started backup task '0cd6e0d9-c9c1-4410-97f4-db57e710aac4'
100: 2026-07-04 01:00:12 INFO: resuming VM again
100: 2026-07-04 01:00:15 INFO:  0% (913.1 MiB of 884.9 GiB) in 3s, read: 304.4 MiB/s, write: 257.9 MiB/s
100: 2026-07-04 01:00:47 INFO:  1% (9.9 GiB of 884.9 GiB) in 35s, read: 288.6 MiB/s, write: 222.9 MiB/s
100: 2026-07-04 01:00:53 INFO:  2% (17.9 GiB of 884.9 GiB) in 41s, read: 1.3 GiB/s, write: 162.1 MiB/s
100: 2026-07-04 01:01:30 INFO:  3% (26.7 GiB of 884.9 GiB) in 1m 18s, read: 245.5 MiB/s, write: 242.4 MiB/s
100: 2026-07-04 01:02:11 INFO:  4% (35.6 GiB of 884.9 GiB) in 1m 59s, read: 220.2 MiB/s, write: 219.9 MiB/s
100: 2026-07-04 01:02:50 INFO:  5% (44.5 GiB of 884.9 GiB) in 2m 38s, read: 234.1 MiB/s, write: 231.7 MiB/s
...
100: 2026-07-04 01:37:40 INFO: 96% (849.8 GiB of 884.9 GiB) in 37m 28s, read: 1.5 GiB/s, write: 157.2 MiB/s
100: 2026-07-04 01:37:45 INFO: 97% (859.8 GiB of 884.9 GiB) in 37m 33s, read: 2.0 GiB/s, write: 102.7 MiB/s
100: 2026-07-04 01:37:50 INFO: 98% (867.8 GiB of 884.9 GiB) in 37m 38s, read: 1.6 GiB/s, write: 117.8 MiB/s
100: 2026-07-04 01:37:55 INFO: 99% (879.0 GiB of 884.9 GiB) in 37m 43s, read: 2.2 GiB/s, write: 76.8 MiB/s
100: 2026-07-04 01:38:04 INFO: 100% (884.9 GiB of 884.9 GiB) in 37m 52s, read: 680.6 MiB/s, write: 125.6 MiB/s
100: 2026-07-04 01:38:04 INFO: backup is sparse: 500.24 GiB (56%) total zero data
100: 2026-07-04 01:38:04 INFO: transferred 884.93 GiB in 2272 seconds (398.8 MiB/s)
100: 2026-07-04 01:38:04 INFO: archive file size: 278.56GB
100: 2026-07-04 01:38:04 INFO: prune older backups with retention: keep-last=3
100: 2026-07-04 01:38:04 INFO: pruned 0 backup(s)
100: 2026-07-04 01:38:04 INFO: Finished Backup of VM 100 (00:37:55)

zfs_send -> full Backup
Code:
[2026-07-14T01:00:11] Base: /media/SmartStore
[2026-07-14T01:00:11] Repo: /media/SmartStore/ResticBackup
[2026-07-14T01:00:14] Repo data size before backup: 361.2 GiB
[2026-07-14T01:00:14] === Starting Proxmox backup ===
[2026-07-14T01:00:15] === Planungsphase (Full/Diff-Bestimmung) ===
[2026-07-14T01:00:17]  VM 100 scsi1: Full noetig (base snapshot autohourly260712160001 missing)
[2026-07-14T01:00:17] === Platzpruefung vor Backup ===
[2026-07-14T01:00:17]  Full-Lauf erkannt -> Full-Run
[2026-07-14T01:00:18]  [Full-Run] Frei: 3363.3 GiB / 3724.6 GiB | Puffer (5%): 186.2 GiB
[2026-07-14T01:00:18]  [Full-Run] SUM_OF_ALL_VM_SIZE (ZFS used aller VM-Disks): 386.8 GiB
[2026-07-14T01:00:18]  [Full-Run] frei - SUM (2976.4 GiB) > Puffer -> kein Pruning noetig
[2026-07-14T01:00:18] --- VM 100 (Win10) ---
[2026-07-14T01:00:21]  OK: config
[2026-07-14T01:00:21]  Config-Snapshot-ID: 1431780e
[2026-07-14T01:00:23]  Full backup (Alles-oder-nichts: mind. eine Disk benoetigt Full)
[2026-07-14T01:00:23]  Full backup: scsi1
[2026-07-14T01:53:39]  OK: scsi1 full (rpool/data/vm-100-disk-0)
[2026-07-14T01:53:39] No LXC containers found
[2026-07-14T01:53:44] Data added this run: 363.0 GiB
[2026-07-14T01:53:44] Disk space: 3000.2 GiB frei von 3724.6 GiB (Warnschwelle 10% = 372.5 GiB)
[2026-07-14T01:53:44] === Proxmox backup complete ===
[2026-07-14T01:53:44] VMs=1 CTs=0 Disks=1 (Full=1 Diff=0) Skipped=0 | Written=363.0 GiB | Errors=0 Warnings=0
[2026-07-14T01:53:44] === Retention: forget + prune ===
[2026-07-14T01:53:44] Policy: keep-daily=10 keep-weekly=3 keep-monthly=2
[2026-07-14T01:53:44] Protecting full backups referenced by kept differentials
[2026-07-14T01:53:45] Nothing to forget
[2026-07-14T01:53:45] === Post-backup integrity check ===
[2026-07-14T01:53:45] Data written this run: 363.0 GiB
[2026-07-14T01:53:45] Checking: 10G (max: 10 GiB)
[2026-07-14T01:55:12] Integrity check passed

zfs_send -> diff Backup (1.)
Code:
[2026-07-15T01:00:11] Base: /media/SmartStore
[2026-07-15T01:00:11] Repo: /media/SmartStore/ResticBackup
[2026-07-15T01:00:17] Repo data size before backup: 724.2 GiB
[2026-07-15T01:00:17] === Starting Proxmox backup ===
[2026-07-15T01:00:17] === Planungsphase (Full/Diff-Bestimmung) ===
[2026-07-15T01:00:20]  Alle Disks differentiell sicherbar -> kein erzwungenes Full
[2026-07-15T01:00:20] === Platzpruefung vor Backup ===
[2026-07-15T01:00:20]  Diff-/LXC-/LOCAL-Lauf -> Diff-Run/No VM
[2026-07-15T01:00:20]  [Diff-Run/No VM] Frei: 3000.2 GiB / 3724.6 GiB | Puffer (5%): 186.2 GiB
[2026-07-15T01:00:20]  [Diff-Run/No VM] Genug frei (>= Puffer) -> kein Pruning noetig
[2026-07-15T01:00:21] --- VM 100 (Win10) ---
[2026-07-15T01:00:23]  OK: config
[2026-07-15T01:00:24]  Config-Snapshot-ID: 5af1fe94
[2026-07-15T01:00:26]  Differential: autodaily260713190002 -> autodaily260714190001
[2026-07-15T01:00:59]  OK: scsi1 diff (rpool/data/vm-100-disk-0)
[2026-07-15T01:01:02]  Age: differential is 1 day(s) after full (9b8c798e)
[2026-07-15T01:01:02] No LXC containers found
[2026-07-15T01:01:07] Data added this run: 3.2 GiB
[2026-07-15T01:01:07] Disk space: 2996.9 GiB frei von 3724.6 GiB (Warnschwelle 10% = 372.5 GiB)
[2026-07-15T01:01:07] === Proxmox backup complete ===
[2026-07-15T01:01:07] VMs=1 CTs=0 Disks=1 (Full=0 Diff=1) Skipped=0 | Written=3.2 GiB | Errors=0 Warnings=0
[2026-07-15T01:01:07] === Retention: forget + prune ===
[2026-07-15T01:01:07] Policy: keep-daily=10 keep-weekly=3 keep-monthly=2
[2026-07-15T01:01:07] Protecting full backups referenced by kept differentials
[2026-07-15T01:01:08] Nothing to forget
[2026-07-15T01:01:08] === Post-backup integrity check ===
[2026-07-15T01:01:08] Data written this run: 3.2 GiB
[2026-07-15T01:01:08] Checking: 4G (max: 10 GiB)
[2026-07-15T01:01:51] Integrity check passed

zfs_send -> diff Backup (3.)
Code:
[2026-07-17T01:00:11] Base: /media/SmartStore
[2026-07-17T01:00:11] Repo: /media/SmartStore/ResticBackup
[2026-07-17T01:00:17] Repo data size before backup: 743.5 GiB
[2026-07-17T01:00:17] === Starting Proxmox backup ===
[2026-07-17T01:00:18] === Planungsphase (Full/Diff-Bestimmung) ===
[2026-07-17T01:00:20]  Alle Disks differentiell sicherbar -> kein erzwungenes Full
[2026-07-17T01:00:20] === Platzpruefung vor Backup ===
[2026-07-17T01:00:20]  Diff-/LXC-/LOCAL-Lauf -> Diff-Run/No VM
[2026-07-17T01:00:20]  [Diff-Run/No VM] Frei: 2980.8 GiB / 3724.6 GiB | Puffer (5%): 186.2 GiB
[2026-07-17T01:00:20]  [Diff-Run/No VM] Genug frei (>= Puffer) -> kein Pruning noetig
[2026-07-17T01:00:21] --- VM 100 (Win10) ---
[2026-07-17T01:00:23]  OK: config
[2026-07-17T01:00:24]  Config-Snapshot-ID: dbebc40f
[2026-07-17T01:00:26]  Differential: autodaily260713190002 -> autodaily260716190002
[2026-07-17T01:05:55]  OK: scsi1 diff (rpool/data/vm-100-disk-0)
[2026-07-17T01:05:58]  Age: differential is 3 day(s) after full (9b8c798e)
[2026-07-17T01:05:59] No LXC containers found
[2026-07-17T01:06:03] Data added this run: 29.4 GiB
[2026-07-17T01:06:03] Disk space: 2951.4 GiB frei von 3724.6 GiB (Warnschwelle 10% = 372.5 GiB)
[2026-07-17T01:06:03] === Proxmox backup complete ===
[2026-07-17T01:06:03] VMs=1 CTs=0 Disks=1 (Full=0 Diff=1) Skipped=0 | Written=29.4 GiB | Errors=0 Warnings=0
[2026-07-17T01:06:03] === Retention: forget + prune ===
[2026-07-17T01:06:03] Policy: keep-daily=10 keep-weekly=3 keep-monthly=2
[2026-07-17T01:06:03] Protecting full backups referenced by kept differentials
[2026-07-17T01:06:04] Nothing to forget
[2026-07-17T01:06:04] === Post-backup integrity check ===
[2026-07-17T01:06:04] Data written this run: 29.4 GiB
[2026-07-17T01:06:04] Checking: 10G (max: 10 GiB)
[2026-07-17T01:07:39] Integrity check passed

RAW -> restic (first run)
Code:
[2026-07-27T01:51:41] Base: /media/SmartStore
[2026-07-27T01:51:41] Repo: /media/SmartStore/ResticBackup
[2026-07-27T01:51:43] === Starting Proxmox backup ===
[2026-07-27T01:51:45] No LXC containers found
[2026-07-27T01:51:45] === Inventory (volumes are resolved and measured once) ===
[2026-07-27T01:51:46]  1 VM disk(s), 0 CT volume(s), 0 local dir(s) | in use: 406.2 GiB
[2026-07-27T01:51:46] === Backup mode check ===
[2026-07-27T01:51:46]  Source data in use: 406.2 GiB | target drive: 930.3 GiB
[2026-07-27T01:51:46]  Needed at AUTO_RAW_FACTOR=2.3: 934.2 GiB
[2026-07-27T01:51:46] [WARNING]  Target drive holds less than 2.3x the source data -> switching to BACKUP_MODE=raw
[2026-07-27T01:51:46] [WARNING]  Reason: a second zfs-send full would not fit; RAW images deduplicate instead of writing a second full copy
[2026-07-27T01:51:46] === Planning phase (full/diff decision) ===
[2026-07-27T01:51:46]  BACKUP_MODE=raw
[2026-07-27T01:51:46]  Result: RAW mode - every volume is stored as a full RAW image, no differentials
[2026-07-27T01:51:47]  vm-100 scsi1: RAW requires ~406.2 GiB
[2026-07-27T01:51:47] === Space required for this run ===
[2026-07-27T01:51:47]  RAW images:    406.2 GiB (always full)
[2026-07-27T01:51:47]  Total required:  406.2 GiB
[2026-07-27T01:51:47] === Space check before backup ===
[2026-07-27T01:51:47]  Required: 406.2 GiB | Free: 532.8 GiB / 930.3 GiB
[2026-07-27T01:51:47]  Enough free space -> no pre-backup pruning needed
[2026-07-27T01:51:50] Repo data size before backup: 397.4 GiB
[2026-07-27T01:51:51] --- VM 100 (Win10) ---
[2026-07-27T01:51:53]  OK: config
[2026-07-27T01:51:54]  Config-Snapshot-ID: a6691eb7
[2026-07-27T01:51:54]  RAW source: ZFS snapshot rpool/data/vm-100-disk-0@autodaily260726190001 via temporary clone rpool/data/vm-100-disk-0_rbclone
[2026-07-27T01:51:54]  RAW image scsi1: /dev/zvol/rpool/data/vm-100-disk-0_rbclone (884.9 GiB, compression=auto)
[2026-07-27T03:11:51]  OK: scsi1 raw
[2026-07-27T03:11:56] Data added this run: 252.3 GiB
[2026-07-27T03:11:56] Disk space: 280.4 GiB free of 930.3 GiB (warning threshold 10% = 93.0 GiB)
[2026-07-27T03:11:56] === Proxmox backup complete ===
[2026-07-27T03:11:56] VMs=1 CTs=0 Disks=1 (Full=0 Diff=0 Raw=1) Skipped=0 | Written=252.3 GiB | Errors=0 Warnings=2
[2026-07-27T03:11:56] === Retention: forget + prune ===
[2026-07-27T03:11:56] Policy: keep-daily=5 keep-weekly=4 keep-monthly=2
[2026-07-27T03:11:57] Nothing to forget
[2026-07-27T03:11:57] === Post-backup integrity check ===
[2026-07-27T03:11:57] Data written this run: 252.3 GiB
[2026-07-27T03:11:57] Checking: 10G (max: 10 GiB)
[2026-07-27T03:15:00] Integrity check passed
[2026-07-27T03:15:00] === Backups in the repository ===
[2026-07-27T03:15:21]  SNAP ID     Backup Time       TYPE     MACHINE    NAME                      DISK              SIZE  PARENT      CONFIG
[2026-07-27T03:15:21]  c60a9f34    2026-07-22 02:00  CONFIG   vm-100     Win10                     -            377.8 GiB  -           c60a9f34
[2026-07-27T03:15:21]  88da2d21    2026-07-22 02:00  FULL     vm-100     Win10                     scsi1        377.8 GiB  -           c60a9f34
[2026-07-27T03:15:21]  f1655cc9    2026-07-23 01:00  CONFIG   vm-100     Win10                     -            382.2 GiB  -           f1655cc9
[2026-07-27T03:15:21]  56df3135    2026-07-23 01:00  DIFF     vm-100     Win10                     scsi1        382.2 GiB  88da2d21    f1655cc9
[2026-07-27T03:15:21]  a7c8506e    2026-07-24 01:00  CONFIG   vm-100     Win10                     -            384.2 GiB  -           a7c8506e
[2026-07-27T03:15:21]  a2b2c759    2026-07-24 01:00  DIFF     vm-100     Win10                     scsi1        384.2 GiB  88da2d21    a7c8506e
[2026-07-27T03:15:21]  53fcb6f6    2026-07-25 01:00  CONFIG   vm-100     Win10                     -            386.5 GiB  -           53fcb6f6
[2026-07-27T03:15:21]  2752e956    2026-07-25 01:00  DIFF     vm-100     Win10                     scsi1        386.5 GiB  88da2d21    53fcb6f6
[2026-07-27T03:15:21]  a6691eb7    2026-07-27 01:51  CONFIG   vm-100     Win10                     -            884.9 GiB  -           a6691eb7
[2026-07-27T03:15:21]  b4acede2    2026-07-27 01:51  RAW      vm-100     Win10                     scsi1        884.9 GiB  -           a6691eb7

RAW -> restic (second run)
Code:
[2026-07-28T01:00:05] Base: /media/SmartStore
[2026-07-28T01:00:05] Repo: /media/SmartStore/ResticBackup
[2026-07-28T01:00:07] === Starting Proxmox backup ===
[2026-07-28T01:00:08] No LXC containers found
[2026-07-28T01:00:08] === Inventory (volumes are resolved and measured once) ===
[2026-07-28T01:00:09]  1 VM disk(s), 0 CT volume(s), 0 local dir(s) | in use: 408.0 GiB
[2026-07-28T01:00:09] === Backup mode check ===
[2026-07-28T01:00:09]  Source data in use: 408.0 GiB | target drive: 930.3 GiB
[2026-07-28T01:00:09]  Needed at AUTO_RAW_FACTOR=2.3: 938.3 GiB
[2026-07-28T01:00:09] [WARNING]  Target drive holds less than 2.3x the source data -> switching to BACKUP_MODE=raw
[2026-07-28T01:00:09] [WARNING]  Reason: a second zfs-send full would not fit; RAW images deduplicate instead of writing a second full copy
[2026-07-28T01:00:09] === Planning phase (full/diff decision) ===
[2026-07-28T01:00:09]  BACKUP_MODE=raw
[2026-07-28T01:00:09]  Result: RAW mode - every volume is stored as a full RAW image, no differentials
[2026-07-28T01:00:15]  vm-100 scsi1: RAW requires ~25.2 GiB
[2026-07-28T01:00:15] === Space required for this run ===
[2026-07-28T01:00:15]  RAW images:    25.2 GiB (always full)
[2026-07-28T01:00:15]  Total required:  25.2 GiB
[2026-07-28T01:00:15] === Space check before backup ===
[2026-07-28T01:00:15]  Required: 25.2 GiB | Free: 280.4 GiB / 930.3 GiB
[2026-07-28T01:00:15]  Enough free space -> no pre-backup pruning needed
[2026-07-28T01:00:19] Repo data size before backup: 649.7 GiB
[2026-07-28T01:00:20] --- VM 100 (Win10) ---
[2026-07-28T01:00:23]  OK: config
[2026-07-28T01:00:23]  Config-Snapshot-ID: 60472f6c
[2026-07-28T01:00:24]  RAW source: ZFS snapshot rpool/data/vm-100-disk-0@autodaily260727190001 via temporary clone rpool/data/vm-100-disk-0_rbclone
[2026-07-28T01:00:24]  RAW image scsi1: /dev/zvol/rpool/data/vm-100-disk-0_rbclone (884.9 GiB, compression=auto)
[2026-07-28T01:26:21]  OK: scsi1 raw
[2026-07-28T01:26:28] Data added this run: 4.1 GiB
[2026-07-28T01:26:28] Disk space: 276.3 GiB free of 930.3 GiB (warning threshold 10% = 93.0 GiB)
[2026-07-28T01:26:28] === Proxmox backup complete ===
[2026-07-28T01:26:28] VMs=1 CTs=0 Disks=1 (Full=0 Diff=0 Raw=1) Skipped=0 | Written=4.1 GiB | Errors=0 Warnings=2
[2026-07-28T01:26:28] === Retention: forget + prune ===
[2026-07-28T01:26:28] Policy: keep-daily=5 keep-weekly=4 keep-monthly=2
[2026-07-28T01:26:29] Nothing to forget
[2026-07-28T01:26:29] === Post-backup integrity check ===
[2026-07-28T01:26:29] Data written this run: 4.1 GiB
[2026-07-28T01:26:29] Checking: 5G (max: 10 GiB)
[2026-07-28T01:28:08] Integrity check passed
[2026-07-28T01:28:08] === Backups in the repository ===
[2026-07-28T01:28:34] SNAP ID   Backup Time    TYPE   MACHINE  NAME           DISK       SIZE PARENT   CONFIG
...
[2026-07-28T01:28:34] b4acede2  2026-07-27 01:51 RAW   vm-100   Win10           scsi1    884.9 GiB -      a6691eb7
[2026-07-28T01:28:34] 60472f6c  2026-07-28 01:00 CONFIG  vm-100   Win10           -      884.9 GiB -      60472f6c
[2026-07-28T01:28:34] 066becbe  2026-07-28 01:00 RAW   vm-100   Win10           scsi1    884.9 GiB -      60472f6c
 
Last edited:
Schöner Direktvergleich, das RAW-vs-zfs_send-Verhalten sieht man da echt gut. Beim extern gezogenen Snapshot frag ich mich noch: ziehst du die cv4pve-autosnap-Snapshots mit aktivem qemu-guest-agent? Im VZDump-Log siehst du ja fs-freeze/fs-thaw, da ist die Platte sauber quiesced. Wenn der Agent mitzieht, passt. Wenn nicht, ist der ZFS-Snapshot vom laufenden Gast nur crash-consistent. Bootet meist trotzdem, aber bei deinem vDC01 wär ich vorsichtig, AD und ntds.dit reagieren empfindlich (USN-Rollback). Bei nem reinen Win10-Client isses ziemlich wurscht.
 
Der Client hat kein Windows 10 mehr. Hab in Inplace Upgrade auf Windows Server gemacht nach Ende von Windows 10. Aber ein AD gibts nicht.

cv4pve-autosnapshots nutzen den qemu-guest-agent. Ich hab schon sporadisch auf einen alten cv4pve Snapshot zurückrollen müssen, das funktioniert aus meiner Sicht sehr gut. Deshalb maße ich mir auch nicht an, den Snapshot selbst zu erstellen; man könnte das Tool aber natürlich so erweitern, dass man cv4pve anstößt, einen Snapshot zu erstellen (und ggf. im Anschluss wieder zu löschen). Hab ich bisher nicht drin, weil ich es selbst nicht brauche.

Ich muss sagen, dass RAW eigentlich uneingeschränkt von Vorteil ggü. zfs_send ist.
Klar, dass ich eine Maschine in 5 min sichern kann, die vorher 4 Stunden gebraucht hat ist in den ersten Tagen nach einem zfs_send full beeindruckend. Aber der Vorteil besteht nur kurz nach dem full, in diesem Verhältnis nur bei großen Maschinen, ... im Mittel steht RAW einfach besser da.

Ich hab mir noch ein ResticRestore gebastelt, mit dem ich mir die RAW-Partitionen direkt aus Restic lokal mounten kann (das funktioniert mit zfs so auch nicht). Ideal, um mal die ein oder andere Datei zurückzuholen – auch wenn ich dafür mittlerweile normalerweise Volumenschattenkopie nutze, die es so aber natürlich nur auf einem Windows Server gibt.
Wenn ich an das Disaster denke, wie man sich eine einzelne Datei aus einem VMA Abbild zieht: Da muss man erst das zstd. Image entpacken und im Anschluss noch das VMA. Auch wenn man beides zusammen in einem Rutsch machen kann: Man benötigt sehr viel freien Speicher für eine kleine Datei.