GIT作为备份工具

在服务器上,安装git

cd / git init git add . git commit -a -m "Yes, this is server" 

然后让/.git/指向一个networking驱动器(SAN,NFS,Samba)或者不同的磁盘。 每小时/每天使用cron作业来更新更改。 .git目录将包含所有服务器文件的版本拷贝(不包括像/ proc,/ dev等无用/复杂的文件)

对于一个不重要的开发服务器,我不希望在适当的备份系统上设置它的麻烦/花费,以及备份只是为了方便(IE我们不需要备份这个服务器,但它会节省有些时候如果事情出错了),这可能是一个有效的备份解决scheme,还是会倒在一大堆便便?

    你不是一个愚蠢的人。 使用git作为备份机制可能会很有吸引力,尽pipe其他人也说过, git对二进制文件工作得很好。 从Git Book中阅读这个页面以获得更多关于这个话题的信息。 基本上,因为git没有使用增量存储机制,所以并不关心你的文件是什么样的(但是对于使用库存configuration的二进制文件, git diff的效用是相当低的)。

    使用git进行备份的最大问题是,它不保留大多数文件系统元数据。 具体来说, git不logging:

    • 文件组
    • 文件所有者
    • 文件权限(除“是这个可执行文件”)
    • 扩展属性

    你可以通过编写工具来将这些信息明确地logging到你的仓库中来解决这个问题,但是要做到这一点很困难。

    谷歌searchgit备份元数据产生了一些看起来值得阅读的结果(包括一些已经试图弥补我在这里提出的问题的工具)。

    etckeeper是为了备份/etc而开发的,解决了许多这些问题。

    我没有使用它,但你可以看看bup这是一个基于git的备份工具。

    它可以是一个有效的备份解决scheme,etckeeper是基于这个想法。 但请留意.git目录的权限,否则在.git目录中可以读取/etc/shadow

    虽然技术上你可以做到这一点,我会提出两个警告:

    1,您正在使用二进制数据源版本控制系统。 因此,您将它用于不适合的东西。

    2,我担心你的开发过程,如果你没有一个过程(文档或自动化)来build立一个新的机器。 如果你碰到了一辆公共汽车,谁知道该怎么做,什么是重要的呢?

    灾难恢复是重要的,但是更好的是自动化(脚本)设置一个新的开发箱,而不仅仅是备份所有的东西。 当然,你的脚本/文档使用git,而不是计算机上的每个文件。

    我使用git作为Windows系统的备份,这非常有用。 在post的底部,我展示了我用来在Windows系统上configuration的脚本。 使用git作为任何系统的备份提供了两大优势:

    1. 与商业解决scheme不同的是,它们经常使用自己的专有格式,因此您的备份采用开源格式,得到了广泛的支持,并且有很好的文档。 这使您可以完全控制您的数据。 很容易看到哪些文件改变了,什么时候改变了。 如果你想截断你的历史,你也可以这样做。 想要从历史中抹去一些东西? 没问题。 获取你的文件的一个版本就像任何git命令一样简单。
    2. 尽可能多或尽可能less的镜像,并且都可以定制备份时间。 你会得到你的本地镜像,这是缓慢的互联网stream量,从而给你(1)能够做更频繁的备份全天(2)快速恢复时间的负担。 (经常备份是一个巨大的优势,因为我发现最多的时间是由于用户错误而丢失了一个文档,例如,你的小孩不小心覆盖了他最近5个小时正在处理的文档。)但是你会得到你的远程镜像,在发生本地灾难或失窃的情况下,具有数据保护的优势。 假设您希望在定制时间备份远程镜像以节省您的Internet带宽? 没问题。

    底线:git备份为您控制备份如何进行提供了令人难以置信的强大function。

    我在我的Windows系统上configuration了这个。 第一步是创build本地git仓库,您将提交所有本地数据。 我build议使用本地的第二块硬盘,但使用相同的硬盘驱动器将工作(但预计你会把它推到远程的地方,否则,如果硬盘驱动器死了,就把它拧紧)。

    您首先需要安装cygwin(与rsync),并且也安装Windows的git: http : //git-scm.com/download/win

    接下来,创build你的本地git仓库(只运行一次):

    INIT-repo.bat:

     @echo off REM SCRIPT PURPOSE: CREATE YOUR LOCAL GIT-REPO (RUN ONLY ONCE) REM Set where the git repository will be stored SET GBKUP_LOCAL_MIRROR_HOME=E:\backup\mirror REM Create the backup git repo. SET GIT_PARAMS=--git-dir=%GBKUP_LOCAL_MIRROR_HOME%\.git --work-tree=%GBKUP_LOCAL_MIRROR_HOME% mkdir %GBKUP_LOCAL_MIRROR_HOME% git %GIT_PARAMS% init git %GIT_PARAMS% config core.autocrlf false git %GIT_PARAMS% config core.ignorecase false git %GIT_PARAMS% config core.fileMode false git %GIT_PARAMS% config user.email backup@yourComputerName git %GIT_PARAMS% config user.name backup REM add a remote to the git repo. Make sure you have set myRemoteServer in ~/.ssh/config REM The path on the remote server will vary. Our remote server is a Windows machine running cygwin+ssh. REM For better security, you could install gitolite on the remote server, and forbid any non-fast-forward merges, and thus stop a malicious user from overwriting your backups. git %GIT_PARAMS% remote add origin myRemoteServer:/cygdrive/c/backup/yourComputerName.git REM treat all files as binary; so you don't have to worry about autocrlf changing your line endings SET ATTRIBUTES_FILE=%GBKUP_LOCAL_MIRROR_HOME%\.git\info\attributes echo.>> %ATTRIBUTES_FILE% echo *.gbkuptest text>> %ATTRIBUTES_FILE% echo * binary>> %ATTRIBUTES_FILE% REM compression is often a waste of time with binary files echo * -delta>> %ATTRIBUTES_FILE% REM You may need to get rid of windows new lines. We use cygwin's tool C:\cygwin64\bin\dos2unix %ATTRIBUTES_FILE% 

    接下来,我们有我们的备份脚本包装,这将被Windows调度程序定期调用:

    gbackup.vbs:

     ' A simple vbs wrapper to run your bat file in the background Set oShell = CreateObject ("Wscript.Shell") Dim strArgs strArgs = "cmd /c C:\opt\gbackup\gbackup.bat" oShell.Run strArgs, 0, false 

    接下来,我们有包装器调用的备份脚本本身:

    gbackup.bat:

      @echo off REM Set where the git repository will be stored SET GBKUP_LOCAL_MIRROR_HOME=E:\backup\mirror REM the user which runs the scheduler SET GBKUP_RUN_AS_USER=yourWindowsUserName REM exclude file SET GBKUP_EXCLUDE_FILE=/cygdrive/c/opt/gbackup/exclude-from.txt SET GBKUP_TMP_GIT_DIR_NAME=git-renamed for /f "delims=" %%i in ('C:\cygwin64\bin\cygpath %GBKUP_LOCAL_MIRROR_HOME%') do set GBKUP_LOCAL_MIRROR_CYGWIN=%%i REM rename any .git directories as they were (see below command) for /r %GBKUP_LOCAL_MIRROR_HOME% %%i in (%GBKUP_TMP_GIT_DIR_NAME%) do ren "%%i" ".git" 2> nul SET RSYNC_CMD_BASE=C:\cygwin64\bin\rsync -ahv --progress --delete --exclude-from %GBKUP_EXCLUDE_FILE% REM rsync all needed directories to local mirror %RSYNC_CMD_BASE% /cygdrive/c/dev %GBKUP_LOCAL_MIRROR_CYGWIN% %RSYNC_CMD_BASE% /cygdrive/c/Users/asmith %GBKUP_LOCAL_MIRROR_CYGWIN% %RSYNC_CMD_BASE% /cygdrive/c/Users/bsmith %GBKUP_LOCAL_MIRROR_CYGWIN% cacls %GBKUP_LOCAL_MIRROR_HOME% /t /e /p %GBKUP_RUN_AS_USER%:f REM rename any .git directories as git will ignore the entire directory, except the main one for /r %GBKUP_LOCAL_MIRROR_HOME% %%i in (.git) do ren "%%i" "%GBKUP_TMP_GIT_DIR_NAME%" 2> nul ren %GBKUP_LOCAL_MIRROR_HOME%\%GBKUP_TMP_GIT_DIR_NAME% .git REM finally commit to git SET GIT_PARAMS=--git-dir=%GBKUP_LOCAL_MIRROR_HOME%\.git --work-tree=%GBKUP_LOCAL_MIRROR_HOME% SET BKUP_LOG_FILE=%TMP%\git-backup.log SET TO_LOG=1^>^> %BKUP_LOG_FILE% 2^>^&1 echo ===========================BACKUP START=========================== %TO_LOG% For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%a-%%b) For /f "tokens=1-2 delims=/:" %%a in ('time /t') do (set mytime=%%a%%b) echo %mydate%_%mytime% %TO_LOG% echo updating git index, committing, and then pushing to remote %TO_LOG% REM Caution: The --ignore-errors directive tells git to continue even if it can't access a file. git %GIT_PARAMS% add -Av --ignore-errors %TO_LOG% git %GIT_PARAMS% commit -m "backup" %TO_LOG% git %GIT_PARAMS% push -vv --progress origin master %TO_LOG% echo ===========================BACKUP END=========================== %TO_LOG% 

    我们有exclude-from.txt文件,我们把所有文件都忽略:

    排除-from.txt:

     target/ logs/ AppData/ Downloads/ trash/ temp/ .idea/ .m2/ .IntelliJIdea14/ OLD/ Searches/ Videos/ NTUSER.DAT* ntuser.dat* 

    你需要去任何远程回购,并对他们做“git init –bare”。 您可以通过执行备份脚本来testing脚本。 假设一切正常,请转到Windows计划程序并将每小时备份指向vbs文件。 之后,你每小时都会有一台计算机的git历史logging。 这是非常方便的 – 每一个意外删除一段文字,错过它? 只要检查你的git存储库。

    那么这不是一个坏主意,但我认为有2个红旗将被提出:

    • 如果硬盘出现故障,如果您不提交到其他服务器/驱动器,则会丢失所有内容。 (事件,如果你有一个计划,我更愿意提到。)

    …但是,它仍然可以成为与腐败有关的事情的一个很好的备份。 或者就像你说的,如果.git /文件夹在别的地方。

    • 这个备份总是会增加大小。 没有修剪或旋转或默认情况下的任何东西。

    …所以你可能需要告诉你的cronjob添加标签,然后确保未被标记的提交将被清除。

    我没有尝试过一个完整的系统,但我用它来做我的MySQL备份(带–skip-extended-insert选项),它对我来说真的很好。

    你会遇到二进制数据文件的问题(他们的整个内容可能会改变),你可能会遇到.git文件夹变得非常大的问题。 我会build议设置一个.gitignore文件,只备份你真正知道你需要的文本文件。

    我曾经开发过基于颠覆的备份解决scheme。 虽然它工作得很好(git应该更好),但我认为这里有更好的解决scheme。

    我认为rsnapshot是一个更好的 – 如果不是更好的。 通过使用硬链接,我有一个300 GB的文件服务器(有50万个文件),每天,每周和每月的备份可以追溯到一年。 总的使用磁盘空间只有一个完整副本+每个备份的增量部分,但是由于硬链接,我在每个备份中都有一个完整的 “实时”目录结构。 换句话说,文件不仅可以在每天的0(最近的备份)下直接访问,而且可以在每天的1(yestarday)或每周的2(两周前)中直接访问,等等。

    使用Samba重新分享备份文件夹,我的用户只需将PC指向备份服务器即可从备份中获取文件。

    另一个非常好的select是rdiff-backup ,但是因为我喜欢只需将资源pipe理器标题为\\ servername就可以访问文件,所以对于我来说,rsnapshot是一个更好的解决scheme。

    我有同样的想法用git备份,主要是因为它允许版本化的备份。 然后我看到了rdiff-backup ,它提供了这个function(还有更多)。 它有一个非常好的用户界面(查看CLI选项)。 我对此很满意。 – --remove-older-than 2W非常酷。 它允许你删除2周以前的版本。 rdiff-backup只存储文件的差异。

    我对git非常陌生,但默认情况下不是分支本地的,并且必须显式地推送到远程仓库? 这是一个令人不快的意外惊喜。 毕竟,我不希望我所有的本地回购“备份”到服务器? 读git书 :

    您的本地分支机构不会自动同步到您写入的遥控器 – 您必须明确推送您想要分享的分支机构。 这样,您可以使用私人分支进行不想分享的工作,并只推送您想要协作的主题分支。

    对我来说,这意味着这些本地分支,就像我本地机器上的其他非git文件一样,有可能会丢失,除非通过一些非git手段定期备份。 无论如何,我这样做,但它打破了我的回购的git'备份一切'的假设。 我很想澄清这一点!

    我发现这对我的开发箱来说是一个很好的方法。 它将它们从需要备份的部分改为仅部署端点。

    所有configuration和软件包安装清单都存储在Puppet中,便于重新部署和configuration更新。 Puppet目录是用git备份的。 Kickstart被用来做最初的部署。

    我还为当时正在开发的任何软件包保留一个自定义的YUM存储库。 这有额外的好处,无论我们正在使用的软件包不只是作为无人值守的二进制文件留在本地系统 – 如果发生这种情况,文件得到nuks哦。 有人没有按照正确的程序。

    您可能想要检查在github上的bup,这是为了使用git进行备份而devise的。

    这是一个使用的方法,这是有道理的。

    Keepconf使用rsync和git来完成这个工作,这是一个包容这个工具的工具,让事情变得简单。

    您只需要一台configuration了ssh-key的中央服务器,用于访问备份服务器和configuration文件中的几行内容。 例如,这是我自己的文件,用于保存所有/ etc /和debian软件包:

     [hosts] 192.168.1.10 192.168.1.11 192.168.1.12 [files] /etc/* /var/lib/dpkg/status 

    与此,我有rsync备份和git提交。

    我个人的意见是,这基本上都是倒退的。 您正在将文件推送到备份解决scheme中,而不是将其拖出。

    更好的办法是首先集中服务器的configuration,然后使用puppet之类的东西把它拉下来。

    也就是说,这可能会起作用,我不认为这会很好。

    尝试寻找backuppc – 它很容易build立,坦率地说是辉煌的。

    这将有所作为,但两个警告。

    1. 进行提交时,文件添加不会自动提取。 使用–porcelean om git状态在提交之前find要添加的新东西。

    2. 为什么远程挂载的.ssh的麻烦? 它变得脆弱Bd你不会知道它失败了。 使用正常的ssh密钥login远端的裸仓库。 只要存储库是裸露的,并且只从一个来源推送,则保证无法合并。