AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1235600
Accepted
Prototype700
Prototype700
Asked: 2020-05-06 02:36:52 +0800 CST2020-05-06 02:36:52 +0800 CST 2020-05-06 02:36:52 +0800 CST

如何在更新系统之前自动创建 Btrfs 快照?

  • 772

我在 Btrfs 根分区上安装了 Ubuntu 20.04 以获取快照功能。

为了使其尽可能简单,我想将 Btrfs 快照的创建集成到我的upgrade-alias 命令中,该命令目前如下所示:

sudo apt update && sudo apt upgrade -y && sudo flatpak update -y && sudo snap refresh

我如何最好地在更新之前添加快照,以便在出现任何问题时可以回滚?

是否也可以同时删除旧快照?(我的根分区填充不到 10%,所以我可以多次复制整个系统,但我想它会很快填满每周更新?)

btrfs scripts updates automation snapshot
  • 4 4 个回答
  • 3446 Views

4 个回答

  • Voted
  1. emk2203
    2020-05-10T04:02:22+08:002020-05-10T04:02:22+08:00

    我会以 Ignacio Nunez Hernanz 的精彩脚本为基础:

    #!/bin/bash
    
    #
    # Script that creates BTRFS snapshots, manually or from cron
    #
    # Usage:
    #          sudo btrfs-snp  <dir> (<tag>) (<limit>) (<seconds>) (<destdir>)
    #
    # Copyleft 2017 by Ignacio Nunez Hernanz <nacho _a_t_ ownyourbits _d_o_t_ com>
    # GPL licensed (see end of file) * Use at your own risk!
    #
    # Based on btrfs-snap by Birger Monsen
    #
    # More at https://ownyourbits.com
    #
    
    function btrfs-snp()
    {
      local   BIN="${0##*/}"
      local   DIR="${1}"
      local   TAG="${2:-snapshot}"
      local LIMIT="${3:-0}"
      local  TIME="${4:-0}"
      local   DST="${5:-.snapshots}"
    
      ## usage
      [[ "$*" == "" ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]] && {
    echo "Usage: $BIN <dir> (<tag>) (<limit>) (<seconds>) (<destdir>)
    
      dir     │ create snapshot of <dir>
      tag     │ name the snapshot <tag>_<timestamp>
      limit   │ keep <limit> snapshots with this tag. 0 to disable
      seconds │ don't create snapshots before <seconds> have passed from last with this tag. 0 to disable
      destdir │ store snapshot in <destdir>, relative to <dir>
    
    Cron example: Hourly snapshot for one day, daily for one week, weekly for one month, and monthly for one year.
    
    cat > /etc/cron.hourly/$BIN <<EOF
    #!/bin/bash
    /usr/local/sbin/$BIN /home hourly  24 3600
    /usr/local/sbin/$BIN /home daily    7 86400
    /usr/local/sbin/$BIN /home weekly   4 604800
    /usr/local/sbin/$BIN /     weekly   4 604800
    /usr/local/sbin/$BIN /home monthly 12 2592000
    EOF
    chmod +x /etc/cron.hourly/$BIN"
    return 0
      }
    
      ## checks
      local SNAPSHOT=${TAG}_$( date +%F_%H%M%S )
    
      [[ ${EUID} -ne 0  ]] && { echo "Must be run as root. Try 'sudo $BIN'" ; return 1; }
      [[ -d "$SNAPSHOT" ]] && { echo "$SNAPSHOT already exists"             ; return 1; }
    
      mount -t btrfs | cut -d' ' -f3 | grep -q "^${DIR}$" || {
    btrfs subvolume show "$DIR" | grep -q "${DIR}$" || {
      echo "$DIR is not a BTRFS mountpoint or snapshot"
      return 1
    }
      }
    
      DST="$DIR/$DST"
      mkdir -p "$DST"
      local SNAPS=( $( btrfs subvolume list -s --sort=gen "$DST" | awk '{ print $14 }' | grep "${TAG}_" ) )
    
      ## check time of the last snapshot for this tag
      [[ "$TIME" != 0 ]] && [[ "${#SNAPS[@]}" != 0 ]] && {
    local LATEST=$( sed -r "s|.*_(.*_.*)|\\1|;s|_([0-9]{2})([0-9]{2})([0-9]{2})| \\1:\\2:\\3|" <<< "${SNAPS[-1]}" )
    LATEST=$( date +%s -d "$LATEST" ) || return 1
    
    [[ $(( LATEST + TIME )) -gt $( date +%s ) ]] && { echo "No new snapshot needed for $TAG"; return 0; }
      }
    
      ## do it
      btrfs subvolume snapshot -r "$DIR" "$DST/$SNAPSHOT" || return 1
    
      ## prune older backups
      [[ "$LIMIT" != 0 ]] && \
      [[ ${#SNAPS[@]} -ge $LIMIT ]] && \
    echo "Pruning old snapshots..." && \
    for (( i=0; i <= $(( ${#SNAPS[@]} - LIMIT )); i++ )); do
      btrfs subvolume delete "$DIR/${SNAPS[$i]}"
    done
    
      echo "snapshot $SNAPSHOT generated"
    }
    
    btrfs-snp "$@"
    
    # License
    #
    # This script is free software; you can redistribute it and/or modify it
    # under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2 of the License, or
    # (at your option) any later version.
    #
    # This script is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this script; if not, write to the
    # Free Software Foundation, Inc., 59 Temple Place, Suite 330,
    # Boston, MA  02111-1307  USA
    

    相关使用信息:

    # btrfs-snp
    Usage: btrfs-snp <dir> (<tag>) (<limit>) (<seconds>) (<destdir>)
    
    dir     │ create snapshot of <dir>
    tag     │ name the snapshot <tag>_<timestamp>
    limit   │ keep <limit> snapshots with this tag. 0 to disable
    seconds │ don't create snapshots before <seconds> have passed from last with this tag. 0 to disable
    destdir │ store snapshot in <destdir>, relative to <dir>
    

    您的升级别名需要如下所示:

    btrfs-snp / syschanges 3 600 && ...它会生成一个带有标签syschanges in的快照/.snapshots,但如果在过去 5 分钟内已经有一个快照,则不会,并且最多保留其中的 3 个。

    这为您提供了 5 分钟的窗口来执行重复操作而不会造成混乱,例如,如果您想在一个安装步骤中从不同的 repos 或 ppa 安装,而不仅仅是升级。

    然后,您可以按照 btrfs 最佳实践使用和恢复这些快照。

    • 1
  2. Best Answer
    Pilot6
    2020-05-10T04:10:43+08:002020-05-10T04:10:43+08:00

    在 中制作快照非常容易btrfs。

    首先将包含btrfs文件系统的分区挂载到例如/mnt. 我们假设它是/dev/sda1.

    sudo mount /dev/sda1 /mnt
    cd /mnt
    

    /如果您使用at@和/homeat安装标准 Ubuntu @home,运行ls将显示两个项目:@和@home.

    此外,如果您之前创建了快照,它们也会显示在那里。

    要创建 and 的快照,请/运行/home以下命令:

    sudo btrfs sub snap @ @-BACKUP && sudo btrfs sub snap @home @home-BACKUP
    

    如果要在创建新备份之前删除现有备份,命令将是:

    sudo btrfs sub del @-BACKUP && sudo btrfs sub del @home-BACKUP
    

    就如此容易。

    完成卸载分区后/mnt :

    sudo umount /mnt
    

    此外,我可以补充一点,您可以创建带有时间戳的快照或进行增量备份。但这有点超出了问题的范围。

    您可以将这些命令组合成一个文本文件,例如backup.sh.

    例子:

    #!/bin/sh
    mount /dev/sda1 /mnt
    cd /mnt
    [ -d @-BACKUP ] && sudo btrfs sub del @-BACKUP #Checks is backup exists and deletes it
    [ -d @home-BACKUP ] && sudo btrfs sub del @home-BACKUP
    btrfs sub snap @ @-BACKUP
    btrfs sub snap @home @home-BACKUP
    cd /
    umount /mnt
    

    该脚本应与sudo.

    • 1
  3. leggewie
    2020-05-14T10:57:11+08:002020-05-14T10:57:11+08:00

    我有几个想法给你。挑选、选择和组合。

    1. 专门构建的现成软件,如apt-btrfs-snapshot或etckeeper,可在幕后自动执行此操作。这可能是最好的前进方式。
    2. 要复制上述软件包的自定义版本,您需要连接到 apt以在每次更新后运行脚本。上述软件包当然可以帮助您了解如何完成此操作的最佳实践,并且在另一个答案中给出了一个复杂脚本的示例。但它也可以是简单的东西btrfs sub snapshot -r /mnt/btrfsroot/@/ /mnt/btrfsroot/snapshots/root-$(date +%y%m%d)。
    3. 在这两种情况下,虽然 apt/dpkg 有这样的钩子,但snap 没有,我不确定其他的。但这不应该是一个真正的问题,因为您根据您的问题首先运行 apt 。
    4. 您最终会得到许多快照,因此您还需要一种手动或自动删除过时快照的方法。为了让您了解如何在假设您的自动快照具有以下路径的情况下完成此操作/mnt/btrfsroot/snapshots/@*-apthook-YYMMDDHH,例如,您可以在每个月的 12 日运行一个 cronjob 作为34 03 12 * * btrfs sub delete /mnt/btrfsroot/snapshots/@*-apthook-$(date --date='15 days ago' +\%y\%m)*. 检查手册页以man 5 crontab获取man date更多信息。

    我希望这能让你朝着正确的方向前进。同样,我建议简单地使用apt-btrfs-snapshot并完成它。请注意,到目前为止,apt-btrfs-snapshot 假设您的根分区名为@. 这是 Ubuntu 和许多其他发行版的默认设置。

    如果有不清楚的地方,请随时提出后续问题。

    PS:你了解/(运行系统的根目录)和 btrfs-root 之间的区别吗?

    • 1
  4. Akib Azmain
    2020-05-13T02:30:25+08:002020-05-13T02:30:25+08:00

    您可以使用这个 shell 脚本轻松地做到这一点。

    使用以下内容创建一个 shell 脚本:

    # Directory for saving snapshots
    SNAPDIR=/snapshots
    export SNAPDIR
    
    # Delete snapshots
    sudo btrfs subvolume delete /mnt/btrfs/backup_*
    
    # Ask user for the name of snapshot
    echo -n "What will be the name of snapshot? "
    read SNAPNAME
    
    # Create the snapshot
    sudo btrfs subvolume snapshot /mnt/btrfs/ $SNAPDIR/backup_$SNAPNAME
    
    # Check if the snapshot created successfully, if not then exit
    if [ $? -ne 0 ]
    then
    echo "Failed to create snapshot"
    exit 1
    fi
    
    # Commands to execute after creating snapshot
    sudo apt update && sudo apt upgrade -y && sudo flatpak update -y && sudo snap refresh
    

    创建文件后,将 /snapshots 替换为您想要保存快照的快照目录。然后放在任何地方。

    现在通过执行使其可执行:

    chmod +x /path/to/shell/script.sh
    

    现在更改升级别名的命令,使其指向脚本。

    现在运行您的别名将首先删除带有backup_前缀的快照,然后它将拍摄以 . 开头的名称保存的文件系统的快照 backup_。

    请注意,第一次运行时,它可能会显示错误。但是第一次运行时忽略它,没有备份,所以没有什么可删除的。也不要backup_在将保存备份快照的目录中创建名称以 at 开头的子卷或快照。这将导致在脚本运行时将其删除。快照也不包括来自其他快照、子卷和挂载分区的文件。

    • 0

相关问题

  • 如何从命令行仅安装安全更新?关于如何管理更新的一些提示

  • iPod Touch (iPhone) 的固件更新?

  • 我如何参与 Ubuntu 的测试和 QA?

  • 如何让 Ubuntu 减少检查更新的频率?对于 11.04 及更高版本对于赶时间的人!通过 Ubuntu 软件中心

  • 如何启用自动更新?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve