使用rSync和SSH创建增量快照式备份
作者:Stephan Jau
修订:v1.5
最后更改:2007年1月16日
基于以下作品:Falko Timme和Mike Rubel <webmaster [at] www [dot] mikerubel [dot] org>
介绍
由于人力和电脑都不完美(人类错误/计算机可能会失败),所以很明显的是,一旦电脑可能下降,一个好的备份系统将会防止太多的损坏。 这可能是因为硬盘出现故障,因为黑客,因为你不小心删除了一些重要的东西,...
在本教程中,我将向您展示如何使用rSync以增量快照风格的方式自动执行备份。
1.通过SSH设置rSync
首先,您需要一个正在运行的rsync服务器和客户端,而不需要输入密码。 更适合甚至通过SSH运行(您可能会传输敏感数据)。 为此,Falko Timme已经写了一个卓越的howto。 您可以在这里找到镜像您的网站与rsync
由于那个技巧已经很好,所以没有必要再写一篇关于这个话题的内容。 按照这样的操作,直到第6步(6,rsync在mirror.example.com上测试) ,并测试你的设置是否有效。
与之前的版本相反,我将只有镜像/备份服务器初始化备份,但我还将显示如何在同一台计算机上进行备份(到不同的分区/磁盘驱动器/ usb棒...)。
注意:在我的情况下,我将数据备份到朋友的服务器上。
2.不自动删除的备份
在此设置中,我将告诉您如何在不删除旧备份的情况下继续进行备份。 对于此设置,这是强制性的,镜像/备份服务器可以访问生产服务器,而不会提示您输入密码。
确保后,您的镜像/备份服务器可以连接到您的生产服务器,而不需要输入密码,那么所有您需要的是一个小的shell脚本和一个cronjob来实际完成备份。
2.添加shell脚本进行备份功能
为了让我们的备份系统运行,我们需要2个shell脚本。 一个在备份/镜像服务器上执行所有作业。 它将启动备份机制。 我已经称它为backup.sh。 另一个将位于生产服务器上。 它所做的就是从你的mysql数据库创建备份(如果你想改变它来备份postgresql或其他一些数据库,如果你明白这一切的工作原理很简单)。
将backup.sh脚本放在备份/镜像服务器上的某个位置,并根据需要调整用户和路径变量。
backup.sh
(备份shell脚本)
#!/bin/bash unset PATH # USER VARIABLES BACKUPDIR=/backup # Folder on the backup server where the backups shall be located KEY=/root/.ssh/id_rsa # SSH key MYSQL_BACKUPSCRIPT=/root/my_backup.sh # Path to the remote mysql backup script PRODUCTION_USER=root@production.server.com # The user and the address of the production server EXCLUDES=/backup/backup_exclude # File containing the excluded directories DAYS=60 # The number of days after which old backups will be deleted # PATH VARIABLES SH=/bin/sh # Location of the bash bin in the production server!!!! CP=/bin/cp; # Location of the cp bin FIND=/usr/bin/find; # Location of the find bin ECHO=/bin/echo; # Location of the echo bin MK=/bin/mkdir; # Location of the mk bin SSH=/usr/bin/ssh; # Location of the ssh bin DATE=/bin/date; # Location of the date bin RM=/bin/rm; # Location of the rm bin GREP=/bin/grep; # Location of the grep bin MYSQL=/usr/bin/mysql; # Location of the mysql bin MYSQLDUMP=/usr/bin/mysqldump; # Location of the mysql_dump bin RSYNC=/usr/bin/rsync; # Location of the rsync bin TOUCH=/bin/touch; # Location of the touch bin ## ## ## -- DO NOT EDIT BELOW THIS HERE -- ## ## ## # CREATING NECESSARY FOLDERS $MK $BACKUPDIR CURRENT=$BACKUPDIR/current OLD=$BACKUPDIR/old $MK $CURRENT $MK $OLD # CREATING CURRENT DATE / TIME NOW=`$DATE '+%Y-%m'-%d_%H:%M` NOW=$OLD/$NOW $MK $NOW # CREATE REMOTE MYSQL BACKUP BY RUNNING THE REMOTE BACKUP SCRIPT $SSH -i $KEY $PRODUCTION_USER "$SH $MYSQL_BACKUPSCRIPT" # RUN RSYNC INTO CURRENT $RSYNC \ -apvz --delete --delete-excluded \ --exclude-from="$EXCLUDES" \ -e "$SSH -i $KEY" \ $PRODUCTION_USER:/ \ $CURRENT ; # UPDATE THE MTIME TO REFELCT THE SNAPSHOT TIME $TOUCH $BACKUPDIR/current # MAKE HARDLINK COPY $CP -al $CURRENT/* $NOW # REMOVE OLD BACKUPS for FILE in "$( $FIND $OLD -maxdepth 1 -type d -mtime +$DAYS )" do # $RM -Rf $FILE # $ECHO $FILE done exit 0
说明:
#!/bin/bash unset PATH # USER VARIABLES BACKUPDIR=/backup # Folder on the backup server KEY=/root/.ssh/id_rsa # SSH key MYSQL_BACKUPSCRIPT=/backup/my_backup.sh # Path to the remote mysql backup script PRODUCTION_USER=root@production.server.com # The user and the address of the production server EXCLUDES=/backup/backup_exclude # File containing the excluded directories DAYS=60 # The number of days after which old backups will be deleted # PATH VARIABLES SH=/bin/sh # Location of the bash bin in the production server!!!! CP=/bin/cp; # Location of the cp bin FIND=/usr/bin/find; # Location of the find bin ECHO=/bin/echo; # Location of the echo bin MK=/bin/mkdir; # Location of the mk bin SSH=/usr/bin/ssh; # Location of the ssh bin DATE=/bin/date; # Location of the date bin RM=/bin/rm; # Location of the rm bin GREP=/bin/grep; # Location of the grep bin MYSQL=/usr/bin/mysql; # Location of the mysql bin MYSQLDUMP=/usr/bin/mysqldump; # Location of the mysql_dump bin RSYNC=/usr/bin/rsync; # Location of the rsync bin TOUCH=/bin/touch; # Location of the touch bin
只需设置上面的相关变量。 我想没有太多的解释
# CREATING NECESSARY FOLDERS MK $BACKUPDIR CURRENT=$BACKUPDIR/current OLD=$BACKUPDIR/old MK $CURRENT MK $OLD # CREATING CURRENT DATE / TIME NOW=`$DATE '+%Y-%m'-%d_%H:%M` NOW=$OLD/$NOW MK $NOW
这将创建必要的文件夹。
# CREATE REMOTE MYSQL BACKUP BY RUNNING THE REMOTE BACKUP SCRIPT $SSH -i $KEY $PRODUCTION_USER "$SH $MYSQL_BACKUPSCRIPT"
这将在生产服务器上运行一个mysql备份脚本。
# RUN RSYNC INTO CURRENT $RSYNC \ -apvz --delete --delete-excluded \ --exclude-from="$EXCLUDES" \ -e "$SSH -i $KEY" \ $PRODUCTION_USER:/ \ $CURRENT ;
该部分将获取生产服务器上的文件,并将其镜像到“当前”文件夹(如脚本顶部的变量中所定义)。
--delete --delete-excluded
这将删除不在产品服务器上的“当前”文件夹中的文件和文件夹。
--exclude-from="$EXCLUDES"
EXCLUDES=/backup/backup_exclude
这将作为备份的排除。 我附上这个文件的当前内容。
/backup/ /bin/ /boot/ /dev/ /lib/ /lost+found/ /mnt/ /opt/ /proc/ /sbin/ /sys/ /tmp/ /usr/ /var/log/ /var/spool/ /var/lib/php4/ /var/lib/mysql/
# REMOVE OLD BACKUPS for FILE in "$( $FIND $OLD -maxdepth 1 -type d -mtime +$DAYS )" do # $RM -Rf $FILE # $ECHO $FILE done exit 0
根据$ DAYS中给出的数字,它将删除所有旧版本的备份。 可以看到remove命令和echo命令都被注释掉。 我建议先检查是否有正确的回波。 通过删除改变行来做到这一点
'# $ECHO $FILE'到这个
' $ECHO $FILE'一旦你确定它会删除正确的文件,再次评论该行,并取消对$ RM命令的行注释。
该部分将获取生产服务器上的文件,并将其镜像到“当前”文件夹(如脚本顶部的变量中所定义)。
my_backup.sh
(mysql备份shell脚本)
该文件需要在您要备份的远程(生产)服务器上 ! 它将备份你的mysql数据库。 下面的脚本会将每个mysql数据库备份到可以还原的单独文件中。 如果要将所有数据库备份到一个文件中,可以使用mysqldump --all-databases ...请参考mysql文档。
但是,如果要进行完整的备份,因为您需要重新设置服务器,那么建议您执行以下操作:在生产服务器上停止mysql(/etc/init.d/mysqld stop),编辑backup_exclude文件并删除从/ var / lib / mysql的行并保存它。 然后运行backup.sh脚本。 这将导致实际的数据库文件将被复制...为了恢复你只需要将它们再次复制到/ var / lib / mysql(或任何你的mysql数据库的存储位置),为什么不应该这样做而mysql正在运行是因为备份的文件可能会被损坏,如果该文件被备份,并且数据库本身有一些改变, 绝对不要依赖于mysql运行时的文件备份!最好是有这里提供的mysql转储脚本和实际文件,当您要重置您的服务器!
#!/bin/bash unset PATH # USER VARIABLES MYSQLUSER=root # The mysql user MYSQLPWD=******************* # The mysql user password MYSQLHOST=localhost # This should stay localhost MYSQLBACKUPDIR=/mysql_backup # A temporary folder where the backupped databases will stay (don't worry, they will be mirrored later # PATH VARIABLES MK=/bin/mkdir; # Location of the mk bin RM=/bin/rm; # Location of the rm bin GREP=/bin/grep; # Location of the grep bin MYSQL=/usr/bin/mysql; # Location of the mysql bin MYSQLDUMP=/usr/bin/mysqldump; # Location of the mysql_dump bin ## ## ## -- DO NOT EDIT BELOW THIS HERE -- ## ## ## # CREATE MYSQL BACKUP # Remove existing backup dir - because we backuped the files before onto our backup server, this is safe to do! $RM -Rf $MYSQLBACKUPDIR # Create new backup dir $MK $MYSQLBACKUPDIR #Dump new files for i in $(echo 'SHOW DATABASES;' | $MYSQL -u$MYSQLUSER -p$MYSQLPWD -h$MYSQLHOST|$GREP -v '^Database$'); do $MYSQLDUMP \ -u$MYSQLUSER -p$MYSQLPWD -h$MYSQLHOST \ -Q -c -C --add-drop-table --add-locks --quick --lock-tables \ $i > $MYSQLBACKUPDIR/$i.sql; done;
现在需要的最后一件事就是做所有的备份。 你可以使用这样的东西:
cron.txt
(cron控制文件)
# Make Backups 0 0,6,12,18 * * * sh /backup/backup.sh
以上将每6小时备份一次。
您可以通过发出以下命令来添加此cron:
crontab cron.txt
请确保先检查您没有其他cron运行。 如果是这样,只需将它们添加到cron控制文件中即可。 列出当前用户的crons:
crontab -l
那么现在享受备份。