{"id":471185,"date":"2025-08-19T03:00:16","date_gmt":"2025-08-19T03:00:16","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=471185"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=471185","title":{"rendered":"<span>My way of a full system backup without external software: incremental rsync plus btrfs with zstd compression<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>The repo of this script is <a href=\"https:\/\/gitlab.com\/vitaly-zdanevich\/full-backup\/-\/blob\/master\/full-backup.sh\" rel=\"noopener noreferrer nofollow\">https:\/\/gitlab.com\/vitaly\u2011zdanevich\/full\u2011backup\/\u2011\/blob\/master\/full\u2011backup.sh<\/a> <\/p>\n<p>Incremental with hard links means that if a file is not changed, on the next backup it will link to the same underlying data, like deduplication. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Hard_link\" rel=\"noopener noreferrer nofollow\">Hard links<\/a>\u00a0\u2014 its usual files. <\/p>\n<p>Also, this script ignores <strong>.gitignore<\/strong> of every folder. <\/p>\n<p>Run this script from another system. <\/p>\n<pre><code class=\"bash\"># Start this script from the git folder of this script # This script accepts the path to the partition to backup (mounted) # Use this script NOT from the system you want to backup - boot from another system  if [ -z \"$1\" ]; then echo \"Missing path of the source (what to backup)\" exit 1 fi  BEFORE=$(df -h)  STARTED=$(date)  DATE=`date \"+%Y-%m-%d\"`  p=$(pwd)  cd $1 # Because rsync --exclude-from accepts only relative paths, not absolute  rsync --archive --acls --xattrs --delete --progress --verbose --exclude-from=$p\/exclude.txt --filter=':- .gitignore' --link-dest=$p\/last --mkpath $1 $p\/$DATE  ln --symbolic --force --no-dereference $DATE last  echo \"Started at:   \" $STARTED echo \"Current time: \" $(date)  echo \"Before:  $BEFORE  Now: \"  df -h  cd -  # How to restore: # # rsync --archive --acls --xattrs --progress --verbose &lt;from&gt; &lt;to&gt; # \/etc\/fstab: alter UUID # grub install (if new SSD) https:\/\/wiki.gentoo.org\/wiki\/Grub: #     grub-install # Note that if SSD is more than 2 GB - you cannot use MBR, only GPT with EFI partition (ThinkPad T430 supports UEFI boot) # emerge-webrsync # emaint sync guru   # Documentation: # https:\/\/jumpcloud.com\/blog\/how-to-backup-linux-system-rsync # https:\/\/wiki.archlinux.org\/title\/rsync<\/code><\/pre>\n<p>      <strong>exclude.txt<\/strong>:<\/p>\n<pre><code class=\"bash\">dev\/* proc\/* sys\/* run\/* # If run on the system that you want to backup  var\/db\/repos\/gentoo var\/db\/repos\/guru var\/cache\/distfiles\/  tmp\/* var\/tmp  lost+found mnt\/*  home\/vitaly\/.npm\/ home\/vitaly\/.cache\/  home\/vitaly\/.zoom\/  home\/vitaly\/.mozilla\/firefox\/*\/storage home\/vitaly\/.config\/google-chrome\/ home\/vitaly\/.config\/chromium\/ home\/vitaly\/.config\/Microsoft\/Microsoft Teams\/ home\/vitaly\/.config\/teams-for-linux\/ home\/vitaly\/.config\/Slack\/ home\/vitaly\/.thumbnails\/  home\/vitaly\/.cache\/ home\/vitaly\/.local\/share\/TelegramDesktop\/tdata\/user_data\/cache\/ home\/vitaly\/.local\/share\/TelegramDesktop\/tdata\/user_data\/media_cache\/ home\/vitaly\/.local\/share\/Steam\/ home\/vitaly\/.googleearth\/Cache\/ home\/vitaly\/.local\/share\/OMaps\/ home\/vitaly\/.config\/Audius\/Cache\/ home\/vitaly\/.config\/YandexMusic\/Cache\/ home\/vitaly\/.config\/vesktop\/sessionData\/Cache\/ home\/vitaly\/.config\/bilibili\/Cache\/ home\/vitaly\/.local\/share\/Trash\/  home\/vitaly\/go\/pkg\/mod\/cache\/ home\/vitaly\/.cargo\/registry\/  home\/vitaly\/record\/out\/  home\/vitaly\/Desktop\/unreal-5-4-4\/<\/code><\/pre>\n<p>My HDD for backups is on <a href=\"https:\/\/en.wikipedia.org\/wiki\/Btrfs\" rel=\"noopener noreferrer nofollow\">btrfs<\/a> for <a href=\"https:\/\/btrfs.readthedocs.io\/en\/latest\/Compression.html\" rel=\"noopener noreferrer nofollow\">ZSTD compression<\/a>, how to prepare the disk: <\/p>\n<pre><code class=\"bash\">sudo apt install btrfs-progs -y # https:\/\/details.nl\/install-and-use-btrfs-on-ubuntu-20-04-lts  sudo mkfs.btrfs \/dev\/sdX # Partitions are not needed  sudo mount -o compress-force=zstd:15 \/dev\/sdX \/mnt # Max compression level is 15 # Default compression you can add to fstab<\/code><\/pre>\n<p>After backup\u00a0\u2014 you can see the compression ratio: <\/p>\n<pre><code class=\"bash\">sudo apt install btrfs-compsize sudo compsize \/mnt<\/code><\/pre>\n<p>Output example:<\/p>\n<pre><code>   Processed 54036 files, 42027 regular extents (42028 refs), 27150 inline.    Type       Perc     Disk Usage   Uncompressed Referenced    TOTAL       73%      211G         289G         289G    zstd        28%       42M         148M         148M    none       100%      174G         174G         174G<\/code><\/pre>\n<p>The main column here is <strong>Perc<\/strong>\u00a0\u2014 lower is better compression. <\/p>\n<p>Besides this backup solution, I store every config in a <a href=\"https:\/\/gitlab.com\/vitaly-zdanevich-configs\" rel=\"noopener noreferrer nofollow\">separate git repository<\/a>, not one repo for all dot files. <\/p>\n<p>Sometimes I use <a href=\"https:\/\/clonezilla.org\/\" rel=\"noopener noreferrer nofollow\">Clonezilla<\/a>\u00a0\u2014 with xz compression of the full drive, for Windows and Linux. <\/p>\n<p>This article is based on my Russian article <a href=\"https:\/\/habr.com\/en\/articles\/929182\" rel=\"noopener noreferrer nofollow\">https:\/\/habr.com\/en\/articles\/929182<\/a>, where people also recommended their backup solutions: <\/p>\n<p> <a href=\"https:\/\/github.com\/jimsalterjrs\/sanoid\/wiki\/Syncoid\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/jimsalterjrs\/sanoid\/wiki\/Syncoid<\/a> <\/p>\n<p> <a href=\"https:\/\/github.com\/jimsalterjrs\/sanoid\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/jimsalterjrs\/sanoid<\/a> <\/p>\n<p> <a href=\"https:\/\/github.com\/bit-team\/backintime\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/bit\u2011team\/backintime<\/a> <\/p>\n<p> <a href=\"https:\/\/github.com\/ei-grad\/trinkup\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/ei\u2011grad\/trinkup<\/a> <\/p>\n<p> <a href=\"https:\/\/restic.net\" rel=\"noopener noreferrer nofollow\">https:\/\/restic.net<\/a> <\/p>\n<p> <a href=\"https:\/\/www.urbackup.org\" rel=\"noopener noreferrer nofollow\">https:\/\/www.urbackup.org<\/a> <\/p>\n<p> <a href=\"https:\/\/www.borgbackup.org\" rel=\"noopener noreferrer nofollow\">https:\/\/www.borgbackup.org<\/a> <\/p>\n<p> <a href=\"https:\/\/kopia.io\" rel=\"noopener noreferrer nofollow\">https:\/\/kopia.io<\/a> <\/p>\n<p> <a href=\"https:\/\/duplicati.com\" rel=\"noopener noreferrer nofollow\">https:\/\/duplicati.com<\/a> <\/p>\n<p> <a href=\"http:\/\/dar.linux.free.fr\" rel=\"noopener noreferrer nofollow\">http:\/\/dar.linux.free.fr<\/a> <\/p>\n<p> <a href=\"https:\/\/fedoramagazine.org\/working-with-btrfs-snapshots\/\" rel=\"noopener noreferrer nofollow\">BTRFS snapshots<\/a> <\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/938448\/\"> https:\/\/habr.com\/ru\/articles\/938448\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>The repo of this script is <a href=\"https:\/\/gitlab.com\/vitaly-zdanevich\/full-backup\/-\/blob\/master\/full-backup.sh\" rel=\"noopener noreferrer nofollow\">https:\/\/gitlab.com\/vitaly\u2011zdanevich\/full\u2011backup\/\u2011\/blob\/master\/full\u2011backup.sh<\/a> <\/p>\n<p>Incremental with hard links means that if a file is not changed, on the next backup it will link to the same underlying data, like deduplication. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Hard_link\" rel=\"noopener noreferrer nofollow\">Hard links<\/a>\u00a0\u2014 its usual files. <\/p>\n<p>Also, this script ignores <strong>.gitignore<\/strong> of every folder. <\/p>\n<p>Run this script from another system. <\/p>\n<pre><code class=\"bash\"># Start this script from the git folder of this script # This script accepts the path to the partition to backup (mounted) # Use this script NOT from the system you want to backup - boot from another system  if [ -z \"$1\" ]; then echo \"Missing path of the source (what to backup)\" exit 1 fi  BEFORE=$(df -h)  STARTED=$(date)  DATE=`date \"+%Y-%m-%d\"`  p=$(pwd)  cd $1 # Because rsync --exclude-from accepts only relative paths, not absolute  rsync --archive --acls --xattrs --delete --progress --verbose --exclude-from=$p\/exclude.txt --filter=':- .gitignore' --link-dest=$p\/last --mkpath $1 $p\/$DATE  ln --symbolic --force --no-dereference $DATE last  echo \"Started at:   \" $STARTED echo \"Current time: \" $(date)  echo \"Before:  $BEFORE  Now: \"  df -h  cd -  # How to restore: # # rsync --archive --acls --xattrs --progress --verbose &lt;from&gt; &lt;to&gt; # \/etc\/fstab: alter UUID # grub install (if new SSD) https:\/\/wiki.gentoo.org\/wiki\/Grub: #     grub-install # Note that if SSD is more than 2 GB - you cannot use MBR, only GPT with EFI partition (ThinkPad T430 supports UEFI boot) # emerge-webrsync # emaint sync guru   # Documentation: # https:\/\/jumpcloud.com\/blog\/how-to-backup-linux-system-rsync # https:\/\/wiki.archlinux.org\/title\/rsync<\/code><\/pre>\n<p>      <strong>exclude.txt<\/strong>:<\/p>\n<pre><code class=\"bash\">dev\/* proc\/* sys\/* run\/* # If run on the system that you want to backup  var\/db\/repos\/gentoo var\/db\/repos\/guru var\/cache\/distfiles\/  tmp\/* var\/tmp  lost+found mnt\/*  home\/vitaly\/.npm\/ home\/vitaly\/.cache\/  home\/vitaly\/.zoom\/  home\/vitaly\/.mozilla\/firefox\/*\/storage home\/vitaly\/.config\/google-chrome\/ home\/vitaly\/.config\/chromium\/ home\/vitaly\/.config\/Microsoft\/Microsoft Teams\/ home\/vitaly\/.config\/teams-for-linux\/ home\/vitaly\/.config\/Slack\/ home\/vitaly\/.thumbnails\/  home\/vitaly\/.cache\/ home\/vitaly\/.local\/share\/TelegramDesktop\/tdata\/user_data\/cache\/ home\/vitaly\/.local\/share\/TelegramDesktop\/tdata\/user_data\/media_cache\/ home\/vitaly\/.local\/share\/Steam\/ home\/vitaly\/.googleearth\/Cache\/ home\/vitaly\/.local\/share\/OMaps\/ home\/vitaly\/.config\/Audius\/Cache\/ home\/vitaly\/.config\/YandexMusic\/Cache\/ home\/vitaly\/.config\/vesktop\/sessionData\/Cache\/ home\/vitaly\/.config\/bilibili\/Cache\/ home\/vitaly\/.local\/share\/Trash\/  home\/vitaly\/go\/pkg\/mod\/cache\/ home\/vitaly\/.cargo\/registry\/  home\/vitaly\/record\/out\/  home\/vitaly\/Desktop\/unreal-5-4-4\/<\/code><\/pre>\n<p>My HDD for backups is on <a href=\"https:\/\/en.wikipedia.org\/wiki\/Btrfs\" rel=\"noopener noreferrer nofollow\">btrfs<\/a> for <a href=\"https:\/\/btrfs.readthedocs.io\/en\/latest\/Compression.html\" rel=\"noopener noreferrer nofollow\">ZSTD compression<\/a>, how to prepare the disk: <\/p>\n<pre><code class=\"bash\">sudo apt install btrfs-progs -y # https:\/\/details.nl\/install-and-use-btrfs-on-ubuntu-20-04-lts  sudo mkfs.btrfs \/dev\/sdX # Partitions are not needed  sudo mount -o compress-force=zstd:15 \/dev\/sdX \/mnt # Max compression level is 15 # Default compression you can add to fstab<\/code><\/pre>\n<p>After backup\u00a0\u2014 you can see the compression ratio: <\/p>\n<pre><code class=\"bash\">sudo apt install btrfs-compsize sudo compsize \/mnt<\/code><\/pre>\n<p>Output example:<\/p>\n<pre><code>   Processed 54036 files, 42027 regular extents (42028 refs), 27150 inline.    Type       Perc     Disk Usage   Uncompressed Referenced    TOTAL       73%      211G         289G         289G    zstd        28%       42M         148M         148M    none       100%      174G         174G         174G<\/code><\/pre>\n<p>The main column here is <strong>Perc<\/strong>\u00a0\u2014 lower is better compression. <\/p>\n<p>Besides this backup solution, I store every config in a <a href=\"https:\/\/gitlab.com\/vitaly-zdanevich-configs\" rel=\"noopener noreferrer nofollow\">separate git repository<\/a>, not one repo for all dot files. <\/p>\n<p>Sometimes I use <a href=\"https:\/\/clonezilla.org\/\" rel=\"noopener noreferrer nofollow\">Clonezilla<\/a>\u00a0\u2014 with xz compression of the full drive, for Windows and Linux. <\/p>\n<p>This article is based on my Russian article <a href=\"https:\/\/habr.com\/en\/articles\/929182\" rel=\"noopener noreferrer nofollow\">https:\/\/habr.com\/en\/articles\/929182<\/a>, where people also recommended their backup solutions: <\/p>\n<p> <a href=\"https:\/\/github.com\/jimsalterjrs\/sanoid\/wiki\/Syncoid\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/jimsalterjrs\/sanoid\/wiki\/Syncoid<\/a> <\/p>\n<p> <a href=\"https:\/\/github.com\/jimsalterjrs\/sanoid\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/jimsalterjrs\/sanoid<\/a> <\/p>\n<p> <a href=\"https:\/\/github.com\/bit-team\/backintime\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/bit\u2011team\/backintime<\/a> <\/p>\n<p> <a href=\"https:\/\/github.com\/ei-grad\/trinkup\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/ei\u2011grad\/trinkup<\/a> <\/p>\n<p> <a href=\"https:\/\/restic.net\" rel=\"noopener noreferrer nofollow\">https:\/\/restic.net<\/a> <\/p>\n<p> <a href=\"https:\/\/www.urbackup.org\" rel=\"noopener noreferrer nofollow\">https:\/\/www.urbackup.org<\/a> <\/p>\n<p> <a href=\"https:\/\/www.borgbackup.org\" rel=\"noopener noreferrer nofollow\">https:\/\/www.borgbackup.org<\/a> <\/p>\n<p> <a href=\"https:\/\/kopia.io\" rel=\"noopener noreferrer nofollow\">https:\/\/kopia.io<\/a> <\/p>\n<p> <a href=\"https:\/\/duplicati.com\" rel=\"noopener noreferrer nofollow\">https:\/\/duplicati.com<\/a> <\/p>\n<p> <a href=\"http:\/\/dar.linux.free.fr\" rel=\"noopener noreferrer nofollow\">http:\/\/dar.linux.free.fr<\/a> <\/p>\n<p> <a href=\"https:\/\/fedoramagazine.org\/working-with-btrfs-snapshots\/\" rel=\"noopener noreferrer nofollow\">BTRFS snapshots<\/a> <\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/938448\/\"> https:\/\/habr.com\/ru\/articles\/938448\/<\/a><br \/><\/br><\/br><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-471185","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/471185","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=471185"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/471185\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=471185"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=471185"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=471185"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}