我看到它将PostgeSQL数据库转储到一个大的SQL文件然后提交并推送到远程Git仓库的方式可能是一个了不起的备份解决方案:我获得了所有版本的历史记录,哈希,安全传输,单向(通过推送真的很难搞乱和删除数据),高效的存储(假设没有二进制文件)并且没有新图像破坏备份的可能性(这是rsync的风险)。
有没有人使用过这种方法,尤其是pg,可以分享他/她的经验吗?缺陷?
答案 0 :(得分:13)
以下是有关如何为postgres执行此操作的完整脚本详细信息。
脚本假设存在一个名为“备份”的用户。可以访问所有(超级用户)或特定数据库。凭据存储在主目录中的.pgpass文件中。该文件看起来像这样(假设密码是'秘密')。
〜/ .pgpass
*:*:*:backup:secret
确保在.pgpass上设置正确的安全性,否则将被忽略
chmod 0600 ~/.pgpass
这会转储特定的数据库。
backup.sh
pg_dump dbname -U backup > backup.sql
git add .
git commit -m "backup"
git push origin master
注意:您可能不希望对数据库转储使用任何文件拆分选项,因为任何插入/删除都会导致“多米诺骨牌”#39;影响并更改所有文件,在git中创建更多的增量/更改。
此脚本将转储整个数据库集群(所有数据库):
pg_dumpall -U backup > backup.sql
git add .
git commit -m "backup"
git push origin master
注意:您可能不希望对数据库转储使用任何文件拆分选项,因为任何插入/删除都会导致“多米诺骨牌”#39;影响并更改所有文件,在git中创建更多的增量/更改。
最后一步是将其添加到cron作业中。所以,' crontab -e'然后添加如下内容(每天午夜运行)
# m h dom mon dow command
# run postgres backup to git
0 0 * * * /home/ubuntu/backupdbtogit/backup.sh
如果您需要恢复数据库,则需要签出要恢复的版本,然后传递给pg。 (有关详细信息,请http://www.postgresql.org/docs/8.1/static/backup.html#BACKUP-DUMP-RESTORE)
对于单个数据库:
psql dbname < infile
整个群集
psql -f infile postgres
这一切都不是特别复杂,但查找所有部分总是很乏味。
我遇到了git在推送时失败的问题。这是由于git使用了大量内存 - 几个提交已备份。我通过在我的本地计算机(具有足够的RAM)上安装服务器git repo来解决了这个问题。我使用sshfs挂载服务器磁盘,然后从我的工作站计算机提交。在我这样做之后,低内存服务器恢复提交没有问题。
更好的选择是在包中限制git的内存使用(来自Is there a way to limit the amount of memory that "git gc" uses?)。
git config --global pack.windowMemory "100m"
git config --global pack.packSizeLimit "100m"
git config --global pack.threads "1"
注意:我还没有尝试设置内存限制,因为我没有再次出现推送失败问题。
答案 1 :(得分:4)
我肯定会推荐它。人们也一直在这样做,主要是围绕MySQL,但我认为没有太大区别:
http://www.viget.com/extend/backup-your-database-in-git/
另一种方法是使用ZFS快照进行备份。
http://www.makingitscale.com/2010/using-zfs-for-fast-mysql-database-backups.html
答案 2 :(得分:4)
通常,您应该使用备份工具进行备份,使用版本控制工具进行版本控制。它们很相似,但不一样。
有些人将这两者混合在一起,例如,基本上数据库中的任何东西都是版本,这不一定是错的,但要明确你想要的东西。
如果您只谈论架构,那么使用Git“备份”可能无法解决问题。但是如果你想备份数据,那么事情会变得复杂。 Git对大文件不是很好。您可以使用git-annex之类的东西来解决这个问题,但是您需要一个单独的备份机制来创建外部文件。此外,使用“适当”的备份方法(如pg_dump或WAL归档)可以提供其他优势,例如能够还原数据库子集或执行时间点恢复。
您可能还想备份操作系统的其他部分。你是怎样做的?最好不要使用版本控制系统,因为它们不能很好地保留文件权限,时间戳和特殊文件。因此,将数据库备份绑定到现有备份系统是有意义的。
答案 3 :(得分:2)
我在$ day_job中做了这个,但它是用MySQL。
我必须编写一个脚本来将单片mysqldump文件整理成单个文件,以便我可以获得不错的差异报告,还因为git可以更好地处理小文件。
该脚本将单片sql文件拆分为单独的sql表模式和数据。
我还必须确保每个sql insert语句不在同一行,以便具有可读的差异报告。
将转储保留在git中的一个优点是我可以运行“git log --stat”来概述哪些表在“备份”的修订版之间发生了变化。