Version 1 backed up in chains: a FULL backup, building on it DIFF and INC backups, each as a pair of meta and image file (.infb/.csfb, .indb/.csdb, .inib/.csib). Version 2 stores deduplicated runs in stores instead. The old format can no longer be read, except with bkp_restore_legacy. This chapter translates the familiar terms and procedures and ends with a checklist for the update.
27.1 Comparison#
| Version 1 | Version 2 |
|---|---|
| Chain (FULL + DIFF/INC) | Store (<store>.cbs) with runs; a store generation is the independent base |
| FULL | the first run of a name in a generation (in lists Full); forced with --type full = new generation |
| DIFF | dropped (--type diff is refused): every run can be restored on its own |
| INC | a normal run (--type inc or without --type), in lists Incremental |
| Synthetic full | no longer needed: every run already is a complete point in time |
| Recompress | dropped; the compression applies per new chunk |
fixed blocks, --block-size | content-dependent chunks, --chunk-size per store or generation |
--parent, --search-dir, --meta, --uuid | --store + --name [--at] or --run |
Meta/image file, bkp_dump <meta> | Run file and packs in the store, bkp_dump <store> --run <run> |
--resume verify|trust, partial backups (.part) on the server | dropped: the next run only sends what the store is missing |
bkp_maintenance partials, m365-check, run-loop | dropped or scrub --store |
--out-encryption, --target-encryption | [sink:] with encryption= and key= |
Target placeholders {meta}/{img} | {store} (and {uuid} for the run) |
Proxmox/Xen: one backup <name>-<disk> per disk | one VM run per VM; single disks with --disk |
27.2 What is different when restoring#
- There is no longer a chain that must be completely present. A run refers directly to all its chunks; the oldest is restored as fast as the newest.
- A point in time is chosen with
--atinstead of the UUID of a certain backup;--runtakes the name from--list. - If a chunk is missing, not the whole restore fails: the area is filled with zeros and reported (partial restore, exit 3), or it comes from another sink.
27.3 Retention and freeing space#
In version 1 a chain stayed until its last link expired, because every INC needed its predecessors; space became free when a whole chain was deleted. In version 2 every run has its own retention, and prune deletes expired runs one by one. After that prune removes the data that no remaining run needs any more (garbage collection).
- An expired run can be deleted at any time, even if older or younger runs stay. There are no dependencies any more.
- Deleting only frees space if the run's chunks are not still needed elsewhere. With stable data this is little: the runs share most of it.
- Protection periods: the newest backup per name always stays; packs younger than
--gc-min-age(24 h) are never touched.
27.4 Damage assessment#
In a chain a damaged block in the FULL made every state building on it unusable at this place, and a new FULL was the fallback. In the store many runs share a chunk; a damaged, often used chunk therefore also hits many runs. There are several protective layers against this:
- Every object has a checksum and is checked against its ID on reading; damage is always detected, never silently written back.
scrubfinds damage early,repairreplaces it from a second copy (second sink or mirror).- The partial restore delivers the rest of a damaged backup and reports exactly which areas are missing.
- A new generation (
--type fullor--store-generation) is like a new FULL used to be: a base that shares no data with the older ones.
27.5 Space display#
Formerly the space of a backup was the size of its files. Today bkp_restore --list shows per run the columns DATA (data of the state), SENT (transferred) and NEW (newly stored). NEW corresponds most closely to the size of a former INC. bkp_maintenance store-info shows the sum of the data of all runs compared with the stored bytes (deduplication factor) and with --exclusive per backup name what only its runs take up, that is what deleting this name would free.
27.6 Schedule before and after#
| Version 1 | Version 2 |
|---|---|
Sundays --type full, weekdays --type inc | daily without --type; Sundays --type full only if an independent base is wanted every week |
Sundays FULL, weekdays --type diff | daily without --type (DIFF is refused, the jobs must be changed) |
| monthly FULL, INC in between | store-generation=1m in the profile, a single daily job |
monthly maint-synthetic-full for an archive | monthly maint-export (archive .cba) or retention retention=12m for the monthly run |
maint-recompress | dropped |
27.7 Checklist for the update at the customer#
- Plan for space: the first backup of every machine into the new store takes as long as a FULL and needs its space; only from the second on is only what is new stored. The old chains lie beside it until they expire.
- Adapt configurations:
block-size=,parent=,type=diff,resume=verify|trust,out-encryption=/target-encryption=(now[sink:]withencryption=/key=),no-vmconfig/no-domconfig,search-dir=,maint-synthetic-full/maint-recompressjobs and{meta}/{img}in the target scheduler are refused (as an unknown key or with a note on the replacement).bkp_sched validateandbkp_target --sched-validatecheck the job configurations; a profile is checked with a trial run by hand. - Fix hash and chunk size: both apply to the store from the first run on. For new stores
--hash blake3, leave the chunk size at the default at first and change it later according to the recommendation ofstore-info. - Keep
bkp_restore_legacyready (setup componentlegacy), best on the backup server where the old files lie: the newbkp_targetdoes not speak the old protocol. - Let old files expire: they are deleted with
bkp_restore_legacy pruneordelete, not withbkp_maintenance.
Reading and deleting old backups
bkp_restore_legacy list /backup # show old backups
bkp_restore_legacy restore --meta /backup/data-20260101T020000Z.inib --target /dev/vg0/data_restored
bkp_restore_legacy prune --search-dir /backup --dry-run # expired old chains