Btrfs

@Snakeeater Unter /media/storage ist das BTRFS-Dateisystem gemounted. Darunter wird dann einmal das Subvolume /media/storage/data und ein reguläres Verzeichnis /media/storage/snapshots erstellt. In diesem Verzeichnis werden die Snapshots des Subvolumes angelegt. Dieses Verzeichnis muss sich innerhalb des selben BTRFS-Dateisystems befinden wie das Subvolume, von dem Snapshots angelegt werden sollen. Sonst funktioniert es nicht.

BTRFS-Send und -Receive sind getrennt, weil man dadurch flexibler ist. So kann man z.B. den Snapshot in eine Datei umleiten:

Bash:
btrfs send /media/storage/snapshots/snapshot-1 > snapshot-1.backup

Und diese Datei dann zu einem anderen Zeitpunkt einspielen:

Bash:
cat snapshot-1.backup | btrfs receive /media/backup

Es ist aber auch üblich das sich Quelle und Ziel auf verschiedenen Rechnern befinden:

Bash:
btrfs send /media/storage/snapshots/snapshot-1 | ssh user@server "btrfs receive /media/backup"

-p /media/storage/snapshots/snapshot-1 ist der Ausgangssnapshot (Parent), welcher sich auch bereits im Ziel /media/backup befinden muss und /media/storage/snapshots/snapshot-2 ist der Name des vorher neu angelegten Snapshots. btrfs send überträgt nun nur die Änderungen, die seit Erstellung von /media/storage/snapshots/snapshot-1 in /media/storage/snapshots/snapshot-2 erfolgt sind.

Hier nochmal der komplette Ablauf:

Bash:
# Anlegen von snapshot-1 des Subvolumes /media/storage/data:
btrfs subvolume snapshot -r /media/storage/data /media/storage/snapshots/snapshot-1
# Übertragen von snapshot-1 auf die Backupplatte:
btrfs send /media/storage/snapshots/snapshot-1 | btrfs receive /media/backup

# Anlegen von snapshot-2 des Subvolumes /media/storage/data:
btrfs subvolume snapshot -r /media/storage/data /media/storage/snapshots/snapshot-2
# Übertragen von snapshot-2 auf die Backupplatte, wobei nur die Änderungen seit snapshot-1 übertragen werden:
btrfs send -p /media/storage/snapshots/snapshot-1 /media/storage/snapshots/snapshot-2 | btrfs receive /media/backup

Auf der Backupplatte befinden sich jetzt snapshot-1 mit allen seinen Dateien und snapshot-2, welcher alle Dateien von snapshot-1 plus alle Änderungen seit dem beinhaltet, wobei die gemeinsamen Dateien von snapshot-1 und snapshot-2, welche sich nicht geändert haben, nur einmal auf der Platte vorhanden sind und entsprechend transparent referenziert werden.
 
  • Gefällt mir
Reaktionen: Piktogramm, Marco01_809, Pummeluff und 2 andere
Ack der III schrieb:
Auf der Backupplatte befinden sich jetzt snapshot-1 mit allen seinen Dateien und snapshot-2, welcher alle Dateien von snapshot-1 plus alle Änderungen seit dem beinhaltet,
Was ist mit den seit snapshot-1 gelöschten Dateien? Die sollten in snapshot-2 ja nicht mehr sein.
Ack der III schrieb:
wobei die gemeinsamen Dateien von snapshot-1 und snapshot-2, welche sich nicht geändert haben, nur einmal auf der Platte vorhanden sind und entsprechend transparent referenziert werden.

So wie ich das verstehe, entspricht das send -p ungefähr dem --link-dest bei rsync, nur das unveränderte Dateien nicht als Hardlinks übernommen werden, sondern per COW, also Reflinks. - Ist das soweit richtig?

Ich sichere schon seit Jahren per "sudo rsync -vaxH --del …“ mit --link-dest auf die vorherige Sicherung, wobei ich jeweils 10 Stufen (0-9) habe: on demand (ich sichere nach jeder gravierenden Änderung) und monatlich (m0-m9) zu Beginn jedes Monats. - Es wird immer in 0 (bzw. m0) gesichert und die Ziffern lasse ich vorher rotieren: Aus 9 wird A, aus 8 wird 9, … und zuletzt aus A 0, das dann auf den aktuellen Stand gebracht wird.

Da ich u. a. wegen der Komprimierung inzwischen auf einigen Sicherungsplatten brtrfs nutze, würde ich es dort gerne mit Snapshots versuchen, wofür mir dein Beispiel eigentlich reichen dürfte (muss ich noch ausprobieren), aber was ist, wenn ich eine weitere Sicherungsplatte auf btrfs umstelle?

Um nicht bei Null anzufangen, kopiere ich bisher einfach alle Sicherungen in einem Rutsch per "sudo rsync -vaxH Pfad-Backup-HD/ Pfad-neuBackup-HD/“ (also jeweils die Root-Verzeichnisse) wobei alle Hardlinks als solche übernommen werden.
(--del braucht es nicht, da die neue Plattte ja leer ist und --link-dest auch nicht, da der Inhalt der Sicherungsplatte als ganzes kopiert wird)

Wie mache ich das bei Snapshots, so dass die Reflinks erhalten bleiben und auf der neuen Platte unveränderte Dateien auch nur 1x Platz belegen?

Ich dachte bisher das wäre gar nicht möglich, da ich btrfs-send und -receive zwar kannte, aber weil damit eine Test-Sicherung aus dem laufenden System heraus schon nicht funktionierte (statt wie bisher mit "sudo rsync -vaxH --del --link-dest=../Sicherung_1/ / Pfad-Backup-HD/Sicherung_0/") hatte ich angenommen für Sicherungen wäre das nicht geeignet, sondern nur für Netzwerke (ich habe keins, nicht mal Festnetz, sondern gehe mit dem PC übers Handy online - deshalb nur selten).
 
Caramon2 schrieb:
Was ist mit den seit snapshot-1 gelöschten Dateien? Die sollten in snapshot-2 ja nicht mehr sein.
Richtig. Zwischen snapshot-1 und snapshot-2 gelöschte Dateien sind in snapshot-2 nicht mehr enthalten. Aber natürlich noch weiterhin in snapshot-1.

Caramon2 schrieb:
So wie ich das verstehe, entspricht das send -p ungefähr dem --link-dest bei rsync, nur das unveränderte Dateien nicht als Hardlinks übernommen werden, sondern per COW, also Reflinks. - Ist das soweit richtig?
Richtig. Der Nachteil über Hardlinks ist jedoch, dass Dateien nicht schreibgeschützt sind und dass das versehentliche Ändern einer Datei alle Varianten mit überschreibt.

Caramon2 schrieb:
Wie mache ich das bei Snapshots, so dass die Reflinks erhalten bleiben und auf der neuen Platte unveränderte Dateien auch nur 1x Platz belegen?
Auch über Snapshots und btrfs-send/receive. Über rsync würde das Dateisystem davon ausgehen, dass die Dateien auf der neuen Platte neue bzw. andere Dateien sind. Jeder Snapshot hat eine eigene ID und mittels send/receive wird auch diese ID sowie alle anderen Metadaten übernommen.

Caramon2 schrieb:
Ich dachte bisher das wäre gar nicht möglich, da ich btrfs-send und -receive zwar kannte, aber weil damit eine Test-Sicherung aus dem laufenden System heraus schon nicht funktionierte
Das laufende System würde ich mit send/receive nicht sichern. Immer nur einen schreibgeschützten Snapshot. Diesen Snapshot kannst du aber vom laufenden System erstellen. Den Snapshot brauchst du später dann sowieso, um ihn als Vorgänger über den Parameter -p angeben zu können.
 
  • Gefällt mir
Reaktionen: Pummeluff, Caramon2 und JumpingCat
Ack der III schrieb:
Caramon2 schrieb:
Wie mache ich das bei Snapshots, so dass die Reflinks erhalten bleiben und auf der neuen Platte unveränderte Dateien auch nur 1x Platz belegen?
Auch über Snapshots und btrfs-send/receive. Über rsync würde das Dateisystem davon ausgehen, dass die Dateien auf der neuen Platte neue bzw. andere Dateien sind. Jeder Snapshot hat eine eigene ID und mittels send/receive wird auch diese ID sowie alle anderen Metadaten übernommen.
rsync ist dabei außen vor. Daas das für Snapshots nicht zu gebrauchen ist, habe ich schon bemerkt. ;)

Schlüssig ist mir das aber trotzdem nicht (letzte Woche habe ich eteas herumprobieren), da in der Manpage von btrfs-suvolume steht, dass in Subvolumen eingebettete Subvolumen von Snapshots nicht erfasst werden und das auch für btrfs-send und btrfs-receive gilt:
Code:
NESTED SUBVOLUMES
       There are no restrictions for subvolume creation, so it's up to the user how to organize them, whether to have a
       flat layout (all subvolumes are direct descendants of the toplevel one), or nested.

       What  should  be mentioned early is that a snapshotting is not recursive, so a subvolume or a snapshot is effec‐
       tively a barrier and no files in the nested subvolumes appear in the snapshot. Instead, there's a  stub  subvol‐
       ume,  also  sometimes  called empty subvolume, with the same name as original subvolume and with inode number 2.
       This can be used intentionally but could be confusing in case of nested layouts.

          $ btrfs subvolume create subvol1
          $ btrfs subvolume create subvol1/subvol2
          $ btrfs subvolume snapshot subvol1 snap1
          $ find -ls
          121093  0  drwxr-xr-x  1  user  users    24  Jul 30  12:34  .
             256  0  drwxr-xr-x  1  user  users    14  Jul 30  12:34  ./subvol1
             256  0  drwxr-xr-x  1  user  users     0  Jul 30  12:34  ./subvol1/subvol2
             257  0  -rw-r--r--  1  user  users     0  Jul 30  12:34  ./subvol1/subvol2/file
             256  0  drwxr-xr-x  1  user  users    14  Jul 30  12:34  ./snap1
               2  0  drwxr-xr-x  1  user  users     0  Jul 30  12:34  ./snap1/subvol2

       The numbers in the first columns are inode numbers, 256 is for a regular subvolume (or snapshot), 2 is the empty
       subvolume. The snapshotted directory representing subvol2 does not contain the file.

       NOTE:
          The empty subvolume will not be sent (btrfs-send(8)) and thus will not be created  on  the  receive  side  (‐
          btrfs-receive(8)).
Aber ich denke das führt hier zu weit, da es darum geht, wie ich meine Datensicherungen (auf ext. Laufwerken) ggfs. durch Snapshots optimieren kann. Dazu plane ich einen eigenen Thread.

Tipp:

Hier habe ich beschrieben und im angehängten Video gezeigt, wie lahm btrfs standardmäßig beim einhängen und der Navigation im Dateimanager ist: Das kann man per "-bgt" (auch nachträglich aktivierbar) stark beschleunigen.

Inzwischen nutze ich auch noch "-n 64k" (m. W. nur beim formatieren möglich), weil das eine weitere deutliche Beschleunigung bringt (z. B. sind meinen Sicherungen auf HDD bis zu 4* schneller: 3 statt 12 Minutrn, aber auch manuelles trimmen einer ext., ca. halb vollen 2 TB SSD (Kingston XS1000) dauert statt über einer Minute nur noch 10-15 Sek., aber auch bei kleineren Partitionen ist es deutlich) und außerdem "-m single" (ich weiß nicht ob man das nachträglich ändern kann): Da mir der Standard (-m dup) noch nie bei Fehlern auf btrfs geholfen hat, möchte ich dafür keinen unnötigen Overhead mehr verschwenden.

Interessant ist, dass seit dem ich diese Optimierungen nutze, noch keine neuen Fehler aufgetreten sind: Vorher dagegen alle paar Monate: Zuletzt vor 1,5 Jahren.
 
Caramon2 schrieb:
in der Manpage von btrfs-suvolume steht, dass in Subvolumen eingebettete Subvolumen von Snapshots nicht erfasst werden
Btrfs erstellt und verwaltet intern für jedes Subvolume eine von den anderen Subvolumes unabhängige Datenstruktur. Dadurch funktioniert der Copy-On-Write-Mechanismus (und damit auch Snapshots) immer nur auf einem Subvolume und nicht subvolume-übergreifend.

Befindet sich ein Subvolume in einem Unterverzeichnis eines anderen Subvolumes, so ist dessen Inhalt von dem übergeordneten Subvolume abgegrenzt. Intern hält das übergeordnete Subvolume nur einen Verweis auf die Datenstruktur des untergeordneten Subvolumes und ist nicht in diesem integriert.

Das muss kein Nachteil sein. Stell dir vor du hast folgende Subvolumes:
Code:
/home
/home/<dein_benutzername>/.local/share/Steam
In dem Steam-Verzeichnis befindet sich der Steam-Client sowie standardmäßig alle heruntergeladenen Spiele.
Wenn du jetzt z.B. mittels rsync ein Backup des Home-Verzeichnisses machen wollen würdest, würdest du sehr wahrscheinlich das Steam-Verzeichnis von dem Backup ausschließen wollen, da das Verzeichnis viel Speicher belegt und die darin enthalten Dateien im Zweifel neu heruntergeladen werden können.

Wäre das Steam-Verzeichnis kein Subvolume und du würdest einen Snapshot vom Home-Subvolume anlegen, so würden die Dateien des Steam-Verzeichnisses auch Teil des Snapshots sein, da ein Snapshot eines Subvolumes nur ganz oder gar nicht erstellt werden kann. Da das Steam-Verzeichnis jedoch ein eigenes Subvolume ist, enthält der Snapshot des Home-Subvolumes alle Dateien des Home-Verzeichnisses ohne die Dateien des Steam-Verzeichnisses, da diese nicht Teil der Datenstruktur des Home-Subvolumes sind.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Pummeluff, Caramon2 und JumpingCat
Ack der III schrieb:
Da das Steam-Verzeichnis jedoch ein eigenes Subvolume ist, enthält der Snapshot des Home-Subvolumes alle Dateien des Home-Verzeichnisses ohne die Dateien des Steam-Verzeichnisses, da diese nicht Teil der Datenstruktur des Home-Subvolumes sind.
Das ist mir schon klar. Es heißt ja oft "Dateisystem im Dateisystem": Wenn "Steam" ein Subvol ist, ist das quasi so, als wäre es eine eingene Partition, die in ~/.local/share/Steam gemountet ist.

Mir geht es darum, dass wenn auf dem ext. Sicherungslaufwerk jede Sicherung ein Subvol ist (mit dem jeweils vorherigen als Referenz erstellt, damit nur die Änderungen übertragen werden), wie kopiere ich alle Sicherungen auf eine neues, frisch formartierte Sicherungslaufwerk, so dass alle Subvols Subvols bleiben und die Reflinks Reflinks, damit die Platzersparnis erhalten bleibt?

Also das Gegenstück zu sudo rsync -vaxH Pfad-altes-Laufwerk/ Pfad-neues-Laufwerk/ bei Hardlinks, womit einfach alles in einem Rutsch kopiert wird und die Hardlinks Hardlinks bleiben.
 
Das wird mit einem Befehl leider nicht gehen. Aber wenn du auf deinem externen Sicherungslaufwerk die Snapshots snapshot1, snapshot2 und snapshot3 hast, kannst du snapshot1 ohne Angabe von Parameter -p auf das neue Sicherungslaufwerk übertragen. Dann snapshot2 mit Angabe von Parameter -p mit Wert snapshot1 und zuletzt snapshot3 mit Angabe von Parameter -p mit Wert snapshot2. Dadurch werden auf dem neuen Sicherungslaufwerk die selben Referenzen wie auf dem ursprünglichen Sicherungslaufwerk angelegt.
 
Zurück
Oben