使用rSync和SSH创建增量快照样式备份

创建增量快照式备份使用rSync和SSHA,人和计算机都不是完美的(人类错误/计算机可能失败)它是相当o ...

使用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

那么现在享受备份。