ZFS und Plattenplatz

Mathias Zunterer

New Member
Jul 16, 2026
3
0
1
München, Germany
Hi all,

Ich hab hier ein Phänomen / Problem, welches ich mir nicht erklären kann.
Ausgangspunkt: PVE 9.2.11; Storage: ZFS raidz2; Am Beispiel eine VM (Windows Server 2025) mit drei Disks:

sata1: proxmox2-sas-zfs:vm-111-disk-0,aio=threads,cache=writeback,format=raw,size=120G
sata2: proxmox2-sas-zfs:vm-111-disk-1,aio=threads,cache=writeback,format=raw,size=3355444M
scsi2: proxmox2-sas-zfs:vm-111-disk-2,aio=threads,cache=writeback,format=raw,iothread=1,size=350G

Mir ist aufgefallen, dass der Storage sehr voll ist, und diese Disks (gefühlt?) zu viel Platz belegen:

# zfs list
NAME USED AVAIL REFER MOUNTPOINT
pxmx2-saspool 6.13T 205G 213K /pxmx2-saspool
pxmx2-saspool/vm-111-disk-0 162G 259G 108G -
pxmx2-saspool/vm-111-disk-1 4.32T 1001G 3.54T -
pxmx2-saspool/vm-111-disk-2 472G 524G 153G -

Mit anderen Worten: Die VM hat disk-1 mit ca 3.2 TByte angelegt, das ZFS Volume ist mit 4.3 TByte erstellt worden; in der VM sehe ich diese Festplatte auch mit der Größe 3276,68 GB (diskmgmt.msc aka "Windows Datenträgerverwaltung"), auch die Werte für die anderen Platten passen mit 120GB und 350GB zu der Definition in der VM, die ZFS Volumes sind aber alle deutlich größer...
Bei einem anderen Proxmox mit ZFS sehe ich hier kaum Differenzen zwischen Größe der ZVols und definierte Größe der virtuellen Disks der VM, allerdings ist das ZFS dort auch "mirror".

Ich will erstmal behaupten dass ich ZFS nicht komplett verstanden habe, aber ich will es verstehen.

Hat jemand eine Idee, woher das "Wachstum" kommen kann, oder kann mich auf die richtigen Stellen schubsen?
Im Storage selbst ist "Thin Provision" nicht aktiviert, Block Size ist 16k (Promox GUI); Snapshost etc. gibts nicht;

Ich habe schon gefunden:

# zfs get reservation
NAME PROPERTY VALUE SOURCE
pxmx2-saspool reservation none default
pxmx2-saspool/vm-111-disk-0 reservation none default
pxmx2-saspool/vm-111-disk-1 reservation none default
pxmx2-saspool/vm-111-disk-2 reservation none default

root@proxmox2:~# zfs list -o space
NAME AVAIL USED USEDSNAP USEDDS USEDREFRESERV USEDCHILD
pxmx2-saspool 205G 6.13T 0B 213K 0B 6.13T
pxmx2-saspool/vm-111-disk-0 259G 162G 0B 108G 54.2G 0B
pxmx2-saspool/vm-111-disk-1 1001G 4.32T 0B 3.54T 797G 0B
pxmx2-saspool/vm-111-disk-2 524G 472G 0B 153G 319G 0B

Hier sieht man, dass USEDREFRESERV sehr groß ist (in etwa die Größenordnung, in der mir der Platz abgeht).
Warum meint ZFS hier soviel Platz zusätzlich reservieren zu müssen? Wenn ich ein zvol mit 3.x TByte habe, welches eine virtuelle Disk einer VM darstellt, dann muss das ZFS doch "nur" 3.x TByte reservieren, unabhängig wieviel Daten wirklich drin liegen; selbst wenn die VM "ihre" disk absolut vollschreibt wird ja das zvol nicht größer. Wofür sind dann die weiteren ~800GB USEDREFRESERV? Und ja, ich will die Disks "thick provisioned", damit ich nicht in die Situation komme, dass eine VM mir den ZFS Pool vollschreibt, aber das wäre -- wenn ich das alles richtig verstanden habe -- auch dann gegeben, wenn USEDREFRESERV 0Byte wäre.

Kann mich jemand erhellen?

Viele Grüße aus München,

Mathias

PS: Diese VM lief mal auf einem ESX, wurde importiert und wieder zurück auf den "jetzt nicht mehr ESX sondern proxmox host" migriert; ich weiß dass "SATA" nicht die beste Wahl ist, das ändere ich noch.
PPS: Ich hab wirklich einiges gesucht, auch hier im Forum, ich bin schlauer geworden, aber klar ist es mir immer noch nicht...
 
Das ist der raidz-Aufschlag auf die refreservation. Schau dir mal die Faktoren an: 120G→162G, 350G→472G, 3,2T→4,32T, das ist bei allen drei Disks exakt 1,35. Kein Zufall. Bei einem thick provisioned zvol legt ZFS die refreservation so aus, dass der Worst Case mit Parity und raidz-Padding garantiert reinpasst. Der Aufschlag hängt dann eben von volblocksize, ashift und Plattenzahl ab. Auf einem Mirror gibts das nicht, weil die Redundanz da schon in der nutzbaren Poolgröße drin steckt. Deshalb passt es auf deiner anderen Kiste.

Der Hebel ist die volblocksize. 16k ist bei ashift 12 nur eine Handvoll Datensektoren pro Block, da kommt Parity plus Padding drauf, prozentual richtig übel. Mit 64k oder 128k wird das Verhältnis deutlich besser, gerade für so eine 3-TB-Datenplatte, die eh keinen random-4k-Workload fährt. Haken: volblocksize lässt sich nicht nachträglich ändern, das zvol muss neu angelegt werden. Also Storage-Default anpassen und die Disk einmal raus und rein, oder Backup/Restore.

Kannst du mal zpool status und zfs get volblocksize,compression,refreservation pxmx2-saspool/vm-111-disk-1 posten? Dann kann ich den 1,35er Faktor mit Plattenzahl und ashift nachrechnen.

Btw, 205G frei bei 6,1T belegt ist schon sportlich. ZFS wird ab ~85% Auslastung spürbar zäh. Und die refreservation kann dir bei der nächsten neuen Disk direkt einen Strich durch die Rechnung machen.
 
  • Like
Reactions: Johannes S and UdoB
Hi Bu66as,

Danke für die Erklärung...
Das ist der raidz-Aufschlag auf die refreservation. Schau dir mal die Faktoren an: 120G→162G, 350G→472G, 3,2T→4,32T, das ist bei allen drei Disks exakt 1,35. Kein Zufall. Bei einem thick provisioned zvol legt ZFS die refreservation so aus, dass der Worst Case mit Parity und raidz-Padding garantiert reinpasst. Der Aufschlag hängt dann eben von volblocksize, ashift und Plattenzahl ab. Auf einem Mirror gibts das nicht, weil die Redundanz da schon in der nutzbaren Poolgröße drin steckt. Deshalb passt es auf deiner anderen Kiste.

Ich dachte immer, dass "zpool list" mir die Brutto-Werte zeigt (hier 10.9TByte), und "zfs list" den effektiv nutzbaren Platz (hier: 6,1TByte), sprich im zvol ist schon Parity etc. eingerechnet. Aber evtl. hänge ich zu sehr in dem alten RAID-Denken...

Kannst du mal zpool status und zfs get volblocksize,compression,refreservation pxmx2-saspool/vm-111-disk-1 posten? Dann kann ich den 1,35er Faktor mit Plattenzahl und ashift nachrechnen.

Danke, zur Info:

Bash:
# zpool list pxmx2-saspool -v
NAME                         SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
pxmx2-saspool               10.9T  7.36T  3.55T        -         -     4%    67%  1.00x    ONLINE  -
  raidz2-0                  10.9T  7.36T  3.55T        -         -     4%  67.5%      -    ONLINE        -
    scsi-35000c500ef1429d7  2.18T      -      -        -         -      -      -      -    ONLINE        -
    scsi-35000c500ef1428c7  2.18T      -      -        -         -      -      -      -    ONLINE        -
    scsi-35000c500ef142a17  2.18T      -      -        -         -      -      -      -    ONLINE        -
    scsi-35000c500ef13f013  2.18T      -      -        -         -      -      -      -    ONLINE        -
    scsi-35000c500ef136fdb  2.18T      -      -        -         -      -      -      -    ONLINE        -

# zfs get volblocksize,compression,refreservation,usedbyrefreservation pxmx2-saspool/vm-111-disk-1 
NAME                         PROPERTY              VALUE           SOURCE
pxmx2-saspool/vm-111-disk-1  volblocksize          16K             default
pxmx2-saspool/vm-111-disk-1  compression           on              inherited from pxmx2-saspool
pxmx2-saspool/vm-111-disk-1  refreservation        4.32T           local
pxmx2-saspool/vm-111-disk-1  usedbyrefreservation  797G            -

Aber das ist ja nur ein Teil, das erklärt die "3,2 zu 4,32 TB". Mir gehts ja zudem um "usedbyrefreservation ", der ja zusätzlich knapp 800GB frisst. Oder bring ich da was durcheinander?


Btw, 205G frei bei 6,1T belegt ist schon sportlich. ZFS wird ab ~85% Auslastung spürbar zäh. Und die refreservation kann dir bei der nächsten neuen Disk direkt einen Strich durch die Rechnung machen.

Ja, weiß ich -- ich hab mit dieser Plattenbelegung auch nicht gerechnet. Ich bin davon ausgegangen, das ich leicht 2 TByte freien Platz hab, das wären deutlich unter 80%.

Viele Grüße,

Mathias

PS: @Impact: Danke für den Hinweis mit den Code Blöcken
 
usedbyrefreservation
Siehe meinen zweiten Link wie du das frei gibst bzw. zu Thin Provisioned umwandelst. Du solltest Thin Provisioning natürlich ebenfalls noch in Datacenter > Storage > proxmox2-sas-zfs für die Zukunft aktivieren. Bei Thin Provisioning is es ist enorm wichtig discard richtig eingerichtet zu haben (erster Link).
 
Last edited:
usedbyrefreservation ist kein zusätzlicher Verbrauch, da bringst du was durcheinander. Das ist der Teil deiner Reservierung, den die VM noch nicht vollgeschrieben hat: 3,54T referenced plus 797G noch offen ergibt die 4,32T. Wenn Windows die Platte weiter füllt, wandert USEDDS hoch und USEDREFRESERV im gleichen Maß runter, die Summe bleibt gleich. Dafür ist thick provisioned da, der Platz ist von vornherein weg, egal wieviel wirklich drin liegt.

Zum RAID-Denken: dein Bauchgefühl stimmt schon, zfs list zeigt netto, die 3/5 aus raidz2 sind da raus. Was da nicht drin ist, ist das Padding pro Block, und das kommt beim zvol obendrauf. Bei ashift 12 (passt zu deinen Zahlen) sind 16k volblocksize gerade mal 4 Datensektoren. raidz2 trägt pro Row nur 3 davon, du brauchst also zwei Rows und damit 4 Paritätssektoren, und dann rundet ZFS die Allokation noch auf ein Vielfaches von 3 auf. Macht 9 Sektoren für 4 Sektoren Nutzdaten, brutto Faktor 2,25, mal 3/5 netto = 1,35. Deine Zahl.

Bei 64k wären es 30 Sektoren für 16, netto ~1,13, bei 128k bist du bei ~1,01. Gerade bei der 3,2T-Datenplatte holst du damit gut ein TB zurück. Nachträglich ändern geht leider nicht, das zvol muss neu angelegt werden, also Storage-Default hoch und die Disk einmal per Backup/Restore durch. Wenn da kein random-4k-Workload drauf läuft, tut 128k performancemäßig auch nicht weh.
 
  • Like
Reactions: Johannes S