From 5b8184be255ad34e89363a72ca07741d95d199e0 Mon Sep 17 00:00:00 2001 From: TW Date: Wed, 13 May 2026 10:02:56 +0200 Subject: [PATCH] docs: add section about rolling back a transaction, fixes #9270 --- docs/usage/notes.rst | 70 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/docs/usage/notes.rst b/docs/usage/notes.rst index dda20cc0f..8ed99ab9e 100644 --- a/docs/usage/notes.rst +++ b/docs/usage/notes.rst @@ -199,6 +199,9 @@ This has some notable consequences: You can manually run compaction by invoking the ``borg compact`` command. +See :ref:`rollback_transaction` for how to undo changes if you have not run +compaction yet. + .. _append_only_mode: Append-only mode (forbid compaction) @@ -231,6 +234,9 @@ Note that you can go back-and-forth between normal and append-only operation wit In append-only mode Borg will create a transaction log in the ``transactions`` file, where each line is a transaction and a UTC timestamp. +See :ref:`rollback_transaction` for how to use this log to roll back the +repository to an earlier state. + In addition, ``borg serve`` can act as if a repository is in append-only mode with its option ``--append-only``. This can be very useful for fine-tuning access control in ``.ssh/authorized_keys``: @@ -244,11 +250,34 @@ Running ``borg init`` via a ``borg serve --append-only`` server will *not* creat an append-only repository. Running ``borg init --append-only`` creates an append-only repository regardless of server settings. -Example -+++++++ +.. _rollback_transaction: + +Rolling back a transaction +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Borg repositories are transactional. A command either succeeds completely and +commits its changes, or it fails (or is interrupted) and the changes are +not committed. + +Furthermore, since Borg 1.2.0, repository space is not freed immediately when +data is marked as deleted (e.g. when archives are deleted or pruned), because +compaction is a separate step (see :ref:`separate_compaction`). This means that +even after a successful commit that deleted data, the old data (and historic +manifests) might still be present in the repository's segment files. + +If you accidentally ran a command that caused data loss (like an incorrect +``borg recreate`` or ``borg prune``), or if your repository was compromised +while in append-only mode, you can roll back the repository to a previous state, +**provided that** ``borg compact`` has not been run since then. + +Rollback in append-only mode +++++++++++++++++++++++++++++ + +In append-only mode, the repository contains a transaction log that makes it +easy to identify stable transactions. Suppose an attacker remotely deleted all backups, but your repository was in append-only -mode. A transaction log in this situation might look like this: +mode. A transaction log (the ``transactions`` file) in this situation might look like this: :: @@ -280,6 +309,41 @@ with file 6:: That's all to do in the repository. +Manual rollback (Undo) +++++++++++++++++++++++ + +If you are not using append-only mode, you can still roll back a transaction +manually by identifying and removing the latest segment files. + +.. note:: + **Make a backup of the repository directory** (e.g. using ``cp -al``) + before doing any manual modifications! Do NOT run ``borg compact``! + +1. **Identify the segment files.** + Look into the repository's ``data/`` directory. Segments are numbered and + grouped into numbered subdirectories. + +2. **Identify the transaction boundaries.** + Each borg operation that modifies the repository creates a transaction, + ending with a commit. The last files of a transaction usually are: + + - **Data segments**: One or more files (up to 500 MB) containing data + chunks (PUT tags) or deletion markers (DEL tags). + - **Manifest**: A small file (a few KB) containing the repository manifest. + - **Commit tag**: A tiny file (17 bytes) marking the end of the transaction. + +3. **Find the previous commit.** + By looking at the segment files in reverse order (highest numbers first), + you can identify the current transaction's commit and manifest, and then + the commit of the *previous* transaction (another 17-byte file). + +4. **Remove the files.** + Delete (or move away) all segment files that were created **after** the + commit of the transaction you want to roll back to. + +After the rollback +++++++++++++++++++ + If you want to access this rolled back repository from a client that already has a cache for this repository, the cache will reflect a newer repository state than what you actually have in the repository now, after the rollback.