digint / btrbk

Tool for creating snapshots and remote backups of btrfs subvolumes
https://digint.ch/btrbk/
GNU General Public License v3.0
1.67k stars 122 forks source link

Sending snapshot to remote only #151

Open Massimo-B opened 7 years ago

Massimo-B commented 7 years ago

For some nocow subvolumes I like to avoid snapshots while still keeping snapshots on the remote backup device (nocow subvolume for Virtual Machines). Snapshotting drops the benefits of nocow as said in the btrfs FAQ, snapshots will increase fragmentation again: https://btrfs.wiki.kernel.org/index.php/FAQ#Can_copy-on-write_be_turned_off_for_data_blocks.3F COW may still happen if a snapshot is taken.

Snapshotting to a remote btrfs only is not possible without creating a snapshot and sending. Then sending-on-the-fly is not supported.

Actually fragmentation happens only after the snapshots was created. It could be possible to create the snapshot, send it to remote and then delete it locally, all while the Virtual Machine is offline. But creating the RO snapshot is done without delay, then sending, then deleting the local one. That is like sending-on-the-fly. Could you add this feature in btrbk? As it knows itself which and when the snapshot was sent so it can delete in locally, like preserve 0.

digint commented 7 years ago

The btrbk behaviour would then be:

  1. create snapshot
  2. send/receive to target
  3. delete snapshot, even if send/receive failed
Massimo-B commented 7 years ago

Exactly. As my current cronjob is

ionice -c 3 /usr/sbin/btrbk -c /etc/btrbk/btrbk.conf run ; btrfs subvolume delete -C /.snapshots/data/*

It would be nice to handle that in the btrbk.conf.

Massimo-B commented 7 years ago

But one issue: I have 2 targets A and B, that are not always available. If none is available, snapshots are only created locally. That means for data, nothing happens as the new snapshot is deleted at once. If a is available, it gets the incremental snapshot which is locally deleted afterwards. If next time B is also available then it doesn't know this latest snapshot as parent but only older ones. How can it get an incremental receive, or does it get a complete source snapshot then?

digint commented 7 years ago

@Massimo-B I don't understand why you delete all your snapshots by hand (i.e. in your cron-job), can't you just set the snapshot_preserve to a reasonable value? Because with this, you possibly delete snapshots which are needed for incremental backups on either A or B.

Your issue above should not happen if you configure both targets in one config file, because btrbk deletes the snapshots required for incremental backups only if send/receive succeeded for BOTH targets.

For your use case, maybe it might be preferable to specify a distinct snapshot_dir for each target (separate A from B). Something like this:

volume /mnt/btr_pool
  subvolume mysubvol
    snapshot_dir  .snapshots/A
    target send-receive A

  subvolume mysubvol
    snapshot_dir  .snapshots/B
    target send-receive B

This way the snapshots in .snapshots/A are deleted on successful send to A, no matter if B is reachable (and vice versa).

If you want only the minimum needed snapshots around, also set snapshot_preserve no, snapshot_preserve_min latest, snapshot_create ondemand.

Massimo-B commented 7 years ago

For this subvolume it is important to have no local snapshots left after btrbk. For now this is not possible, as snapshot_preseve_min can't be zero. This issue ticket is about setting this to zero so that btrbk deletes the local snapshot after sending.

It is important because this subvolume contains virtual machines doing random writes. Issues with btrfs and such data only arise if there is a snapshot. Without a snapshot no fragmentation is happening. Actually when running the btrbk and temporarily creating the local snapshot, the virtual machine must not be running, but those are running only occasionally and btrbk snapshotting is quick. However on the remote target I like to have all the btrbk convenience having some snapshots from times before while sharing space by COW.

digint commented 7 years ago

Ah I see. I was not sure because you were talking about incremental backups, which is not possible as soon as the latest common subvolume is deleted.

How can it get an incremental receive, or does it get a complete source snapshot then?

So no, if you always delete all snapshots on the source side there will be no incremental. It either "live with fragmentation and have incremental backups", or "no fragmentation but also no incremental backups".

I have not yet found a simple solution for this use case, probably I will introduce something like snapshot_create oneshot, but then I'll also have to adapt snapshot_preserve_min (ability to be set to "no"), which might introduce some other quirks...