题 GIT作为备份工具


在服务器上,安装git

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

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

对于一个非重要的开发服务器,我不希望在适当的备份系统上设置它的麻烦/成本,并且备份只是为了方便(I.E.我们不 需要 备份这台服务器,但如果出现问题会节省一些时间),这可能是一个有效的备份解决方案,还是只会在一大堆大便中摔倒?


88
2017-12-15 12:10




使用类似的想法不闪耀? - B14D3
@ B14D3我觉得sparkleshare更像是一种Dropbox类型,但我会调查一下 - Smudge
你是对的,但它使用git制作某种buckup的东西(复制到几个pc和控制文件的版本);) - B14D3
这方面的一个大问题是没有中央控制 - 您需要直接(ssh)访问机器以执行任何形式的维护或备份验证。我总是发现在要备份的盒子上安装应用程序,然后从中心位置管理它们是一个更大的胜利。 - hafichuk
@hafichuk有了像Puppet / Chef这样的工具,这不是一个大问题,但我明白你的观点。 - Smudge


答案:


你不是一个愚蠢的人。运用 git 作为备份机制可能很有吸引力,尽管其他人说过, git 使用二进制文件可以正常工作。读 这个页面来自Git Book 有关此主题的更多信息。基本上,从那以后 git 没有使用增量存储机制,它并不真正关心 什么 你的文件看起来像(但实用程序 git diff 具有库存配置的二进制文件非常低)。

使用的最大问题 git 备份是因为它不保留大多数文件系统元数据。特别, git 不记录:

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

您可以通过编写工具将此信息明确记录到您的存储库中来解决这个问题,但要做到这一点可能会很棘手。

谷歌搜索 git备份元数据 产生了一些看似值得阅读的结果(包括一些已经尝试补偿我在这里提出的问题的工具)。

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


78
2017-12-15 17:25



+1提及ACL /权限 - Larry Silverman
Git也不存储空目录。 - Flimm
并且通过历史记录跟踪文件移动/重命名也很糟糕。 - cregox
由于git不能很好地处理二进制文件,您可能还需要研究一下 git附件,这有助于做得更好。然而,它确实改变了git的概念。 - Wouter Verhelst
我的意见是你可以使用git备份数据而不是整个服务器 - EKanadily


我没用过它,但你可能会看一下 BUP 这是一个基于git的备份工具。


20
2017-12-15 13:27



从未见过bup,看起来很有趣 - Smudge
我最近开始使用bup,就在我的硬盘崩溃前几天;)恢复正常,所以建议! - André Paramés
@AndréParamés所以你所说的只是在你安装了你的硬盘崩溃之后... mmmmhh ...... :)开玩笑 - hofnarwillie


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


12
2017-12-15 12:18





虽然从技术上讲你可以做到这一点我会对它提出两点警告:

1,您正在使用二进制数据的源版本控制系统。因此,您正在使用它不是为其设计的东西。

2,如果您没有构建新机器的流程(文档或自动化),我会担心您的开发过程。如果你受到打击怎么办买车,谁会知道该做什么和什么是重要的?

灾难恢复很重要,但是自动化(脚本)新开发盒的设置比仅备份一切更好。当然可以使用git作为脚本/文档,但不能使用计算机上的每个文件。


11
2017-12-15 13:45



开发盒都来自KickStart文件,实际上平均盒子在重建之前大约持续2或3个月。但是人们改变了配置并做了事情,我们重新构建了盒子,人们说“嘿,我知道我没有把它放在源代码控制中,但我在那个盒子上有一些东西”,我嘲笑他们是愚蠢的。周围,​​美好的时光。二进制数据将是一个婊子,这是我在淋浴时完全忽略的东西。 - Smudge
我赞赏你对那些不遵循基本原则的人的态度。就个人而言,我有类似的情况,但是我有一个git存储库,它链接所有可能很重要的配置文件,而不是全部捕获。加上带有设置步骤的txt doc。 - Phil Hannent
我认为git适用于二进制文件,视频谷歌Android的大部分回购都是预构建可执行文件的git存储库。 - user377178


我使用git作为我的Windows系统的备份,它非常有用。在帖子的底部,我展示了用于在Windows系统上配置的脚本。使用git作为任何系统的备份提供了两大优势:

  1. 与商业解决方案通常使用自己的专有格式不同,您的备份采用开源格式,受到广泛支持且记录良好。这使您可以完全控制数据。很容易看到哪些文件发生了变化,何时发生变化。如果要截断历史记录,也可以这样做。想要从历史中抹去某些东西?没问题。获取文件的版本就像任何git命令一样简单。
  2. 您可以根据需要选择多个或多个镜像,并且所有镜像都可以定制备份时间。您将获得本地镜像,它不会受到缓慢的Internet流量的负担,从而使您(1)能够在一天中进行更频繁的备份,以及(2)快速恢复时间。 (频繁的备份是一个巨大的优势,因为我发现丢失文档的时间最多的是用户错误。例如,你的孩子不小心会覆盖他过去5个小时一直在处理的文档。)但是你会得到你的远程镜像,在本地灾难或被盗时提供数据保护的优势。并且假设您希望在定制时间备份远程镜像以节省Internet带宽?没问题。

结论:git备份为您提供了令人难以置信的功能,可以控制备份的发生方式。

我在Windows系统上配置了这个。第一步是创建本地git仓库,您将提交所有本地数据。我建议使用本地的第二个硬盘驱动器,但使用相同的硬盘驱动器将起作用(但是预计你会将它推到远处,或者如果硬盘驱动器死亡,你会搞砸。)

您首先需要安装cygwin(使用rsync),还需要为Windows安装git: http://git-scm.com/download/win

接下来,创建本地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 Scheduler将定期调用它:

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'。您可以通过执行备份脚本来测试脚本。假设一切正常,请转到Windows Scheduler并将每小时备份指向vbs文件。之后,您将获得每小时计算机的git历史记录。这非常方便 - 每次意外删除一段文字而错过了吗?只需检查您的git存储库。


6
2018-03-21 17:10



只是好奇 - 它是否也适用于慢速或非标准网络驱动器,如NetDrive或Expandrive模拟的驱动器?我发现大多数备份软件都没有使用这些网络驱动器。如果我想列出备份中的所有文件并提取单个文件,那么事情会变得非常缓慢并且趋于超时。 git能解决这些问题吗? - JustAMartin
@JustAMartin我从未在网络驱动器上测试它,所以我不能说。一旦你获得了git repo中的文件,git非常有效。 - user64141


嗯,这不是一个坏主意,但我认为有两个红旗要提出:

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

......但是,它仍然是腐败相关事物的良好备份。或者就像你说的,如果.git /文件夹在其他地方。

  • 此备份的大小将始终增加。默认情况下没有修剪或旋转或任何东西。

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


4
2017-12-15 13:40



我们可能会将.git目录挂载到远程服务器上,尽管是clasic rm -Rf / 会引起我们一些问题。我们目前的备份系统可以保存2年或50个版本(以最后者为准),因此无论如何我们的备份都在不断增加。但我喜欢添加标签的想法,我们可以有“每日”,“每周”等标签 - Smudge
+1用于不断增长的空间需求 - hafichuk
@sam git一直在增长。你可以修剪超过N年的历史。我想你现在的系统确实如此。 - rds
关于增加大小,请定期或在推送到另一个(中央)服务器之前执行'git gc'。如果没有这个,git repo可能会比它应该增长(更大)。我曾经有一个346 MB的git repo,可以缩小到16 MB。 - Hendy Irawan


我没有尝试使用完整的系统,但我将它用于我的MySQL备份(使用--skip-extended-insert选项),它对我来说真的很好用。

您将遇到二进制数据文件的问题(它们的整个内容可能会发生变化)并且您可能遇到问题 .git 文件夹变得非常大。我建议你设置一个 .gitignore 文件,只备份您确实需要的文本文件。


3
2017-12-15 13:23



我也使用它进行MySQL备份,使用--extended-insert = false。确保定期或在提交后立即“git gc”。 - Hendy Irawan
看到 在Git备份MySQL数据库是个好主意吗? - Michael Hampton♦