linux下如何实现增量备份?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux下如何实现增量备份?相关的知识,希望对你有一定的参考价值。

服务器系统为linux,每月都有版本升级,这就需要对原程序代码进行备份。备份的方式我想实现增量备份,而非全量备份,即将服务器现有代码与版本升级内容做比较,若有相同目录下的相同文件,则将此文件连同目录一起备份。
比如:原程序代码platform/test文件夹下的a文件为这次的升级内容,则我的备份为platform/test/a 望高手指点,急,分数不多了,还望包涵!

服务器需求:
  需要备份文件的服务器(服务器端):192.168.10.2 (RHEL 5)

  接收备份文件的服务器(客户端):192.168.10.3 (RHEL 5)

  实现功能:

  通过rsync工具对turbomail邮件服务器的accounts目录和conf目录进行增量备份。

  accounts目录:用于存储用户相关信息的目录

  conf目录:用户配置文件存放目录

  前提条件:

  先将turbomail邮件系统安装好(服务器端与客户端操作一样)

  安装过程如下:

  1、挂载光驱:mount /dev/cdrom

  2、将turbomail的安装包拷贝到跟目录下/

  #cd /dev/cdrom

  #cp turbomail_linux_x86_xxx.tgz

  3、解压turbomail安装包

  tar –zxvf turbomail_linux_x86_xxx.tgz

  4、启动turbomail

  #cd /turbomail

  #./starttm.sh

  #cd /turbomail/web/bin/

  #./startup.sh 5、修改启动脚本/etc/rc.d/rc.local
使邮件服务器开机自动启动加入以下几行:#/turbomail/starttm.sh &
#/turbomail/web/bin/startup.sh & #/turbomail/safestart.sh &

  rsync的配置如下:

  1.服务器端rsync的配置:使用系统自带的rsync工具,插入系统启动光盘,通过rpm安装rsync工具。

  若采用采用源码包安装,上传安装包到服务器1)tar –zxvf rsyncrsync-2.6.9.tar.gz #解压2)cd rsyncrsync-2.6.9 3)./configure #默认配置,生成编译环境

  4)make #编译

  5)make install #安装完成,任何步骤有疑问输入echo $?查返回值,0表示成功,其他都为失败rsync 版本
2.4.6(可以从http://rsync.samba.org/rsync/获得最新版本)
1)编辑/etc/rsyncd.conf文件,rsync的主要配置文件:

  #[globale]

  strict modes= yes

  #check passwd file

  port= 873 #rsync工具默认使用的端口

  #default port

  logfile= /var/log/rsyncd.log #日志文件存放路径pidfile= /var/run/rsyncd.pid #记录rsync运行时的进程ID

  max connections= 4 #同上最大的链接数

  #[modules] #同步模块的配置

  [rsync]

  uid= root #该选项指定当该模块传输文件时守护进程应该具有的uid

  gid= root #该选项指定当该模块传输文件时守护进程应该具有的gid

  ignore errors #忽略一些无关的错误信息

  #要备份的目录

  path= /turbomail/accounts #需要同步的目录

  read only= no #是否设置以只读的方式运行

  host allow= 192.168.10.3 #同步数据的客户端ip如有多个客户端,以“,”隔开即可

  auth users= zhouhw #同步用的用户名

  secrets file= /etc/rsyncd.scrt #同步的密码认证文件

  [test]

  uid= root #该选项指定当该模块传输文件时守护进程应该具有的uid

  gid= root #该选项指定当该模块传输文件时守护进程应该具有的gid

  ignore errors #忽略一些无关的错误信息

  #要备份的目录

  path= /turbomail/conf #需要同步的目录

  read only= no #是否设置以只读的方式运行

  host allow= 192.168.10.3 #同步数据的客户端ip如有多个客户端,以“,”隔开即可

  auth users= zhouhw #同步用的用户名

  secrets file= /etc/rsyncd.scrt #同步的密码认证文件2)编辑/etc/rsyncd.scrt文件,密码认证文件

  zhouhw:123456

  该更权限为600:chmod 600 /etc/rsyncd.scrt 3) 运行rsync --daemon,并在/etc/rc.d/rc.local加入此语句,开机自动启动。

  备注:rsync默认端口873,若安装了iptables,如需改动启动时启动rsync –port 873,请在iptables 中开放该端口,语句如下:

  iptables -I INPUT -p tcp --dport 873 -j ACCEPT

  4)编辑/etc/xinetd.d/rsync

  rsync服务的监听由xinet来统一分配:

  service rsync

  

  disable = no #将此项改为no

  socket_typ
e = stream
  wait = no

  user = root

  server = /usr/bin/rsync

  server_args = --daemon

  log_on_failure += USERID

  

  重启xinetd以启动rsync服务

  service xinetd restart

  5)查看rsync事故正常运行

  输入命令:netstat -ant|grep :873若有显示以下一条语句,则说明rsync服务已经正常启动了。

  tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 2.客户端的配置:使用系统自带的rsync工具,插入系统启动光盘,通过rpm安装rsync工具。

  1)编辑/etc/rsyncd.scrt文件,密码认证文件

  zhouhw:123456

  该更权限为600:chmod 600 /etc/rsyncd.scrt 2)编辑脚本vi /root/scrpit/rsync.sh并加入开机自动启动。

  #!/bin/sh /usr/bin/rsync -vazu --progress --delete
zhouhw@192.168.10.2::rsync /turbomail --password-file=/etc/rsyncd.scrt
zhouhw@192.168.10.2::test /turbomail
--password-file=/etc/rsyncd.scrt修改权限:chmod u+x
/root/scrpit/rsync.sh执行./rsync.sh 同步数据。

  3)编辑/etc/crontab文件,定义为每小时30分钟执行一次数据同步。

  vi /etc/crontab

  # run-parts

  01 * * * * root run-parts /etc/cron.hourly 02 4 * * * root
run-parts /etc/cron.daily 22 4 * * 0 root run-parts /etc/cron.weekly 42 4
1 * * root run-parts /etc/cron.monthly 30 * * * * root
/root/scrpit/rsync.sh客户端的配置到此就可以了,服务器与客户端的数据也会在每小时的第30分钟执行一次。

  客户端同步命令详解:

  v, --verbose 详细模式输出-q, --quiet 精简输出模式-c, --checksum
打开校验开关,强制对文件传输进行校验-a, --archive 归档模式,表示以递归方式传输文件,并保持所有文件属性,等于-rlptgoD
-r, --recursive 对子目录以递归模式处理-R, --relative 使用相对路径信息-b, --backup
创建备份,也就是对于目的已经存在有同样的文件名时,将老的文件重新命名为~filename。可以使用--suffix选项来指定不同的备份文件前缀。

  --backup-dir 将备份文件(如~filename)存放在在目录下。

  -suffix=SUFFIX定义备份文件前缀

  -u, --update 仅仅进行更新,也就是跳过所有已经存在于DST,并且文件时间晚于要备份的文件。(不覆盖更新的文件) -l, --links 保留软链结-L, --copy-links 想对待常规文件一样处理软链结

  --copy-unsafe-links仅仅拷贝指向SRC路径目录树以外的链结

  --safe-links忽略指向SRC路径目录树以外的链结

  -H, --hard-links 保留硬链结-p, --perms 保持文件权限-o, --owner 保持文件属主信息-g,
--group 保持文件属组信息-D, --devices 保持设备文件信息-t, --times 保持文件时间信息-S, --sparse
对稀疏文件进行特殊处理以节省DST的空间-n, --dry-run现实哪些文件将被传输-W, --whole-file
拷贝文件,不进行增量检测-x, --one-file-system 不要跨越文件系统边界-B, --block-size=SIZE
检验算法使用的块尺寸,默认是700字节-e, --rsh=COMMAND 指定替代rsh的shell程序

  --rsync-path=PATH指定远程服务器上的rsync命令所在路径信息

  -C, --cvs-exclude 使用和CVS一样的方法自动忽略文件,用来排除那些不希望传输的文件--existing 仅仅更新那些已经存在于DST的文件,而不备份那些新创建的文件

  --delete删除那些DST中SRC没有的文件

  --delete-excluded同样删除接收端那些被该选项指定排除的文件

  --delete-after传输结束以后再删除

  --ignore-errors及时出现IO错误也进行删除

  --max-delete=NUM最多删除NUM个文件

  --partial 保留那些因故没有完全传输的文件,以是加快随后的再次传输--force 强制删除目录,即使不为空

  --numeric-ids不将数字的用户和组ID匹配为用户名和组名

  --timeout=TIME IP超时时间,单位为秒-I, --ignore-times
不跳过那些有同样的时间和长度的文件--size-only
当决定是否要备份文件时,仅仅察看文件大小而不考虑文件时间--modify-window=NUM 决定文件是否时间相同时使用的时间戳窗口,默认为0

  -T --temp-dir=DIR在DIR中创建临时文件

  --compare-dest=DIR同样比较DIR中的文件来决定是否需要备份

  -P等同于--partial

  --progress显示备份过程

  -z, --compress 对备份的文件在传输时进行压缩处理

  --exclude=PATTERN指定排除不需要传输的文件模式

  --include=PATTERN指定不排除而需要传输的文件模式

  --exclude-from=FILE排除F
ILE中指定模式的文件
  --include-from=FILE不排除FILE指定模式匹配的文件

  --version打印版本信息

  --address绑定到特定的地址

  --config=FILE 指定其他的配置文件,不使用默认的rsyncd.conf文件

  --port=PORT指定其他的rsync服务端口

  --blocking-io对远程shell使用阻塞IO

  -stats给出某些文件的传输状态

  --progress在传输时现实传输过程

  --log-format=formAT指定日志文件格式

  --password-file=FILE从FILE中得到密码
  --bwlimit=KBPS 限制I/O带宽,KBytes per second -h, --help 显示帮助信息
参考技术A 源代码的备份?
为什么不上 cvs 、svn 、 git 这种源代码管理系统来管理?
他们是基于版本控制的。
可以方便的导出代码变动,某特定版本的代码,最新代码等等,很多功能的。

至于增量备份,tar 就可以,不过他是打包备份。
你也可以选择检测每个文件的修改日期,在某个日期之后的文件复制出来就可以了。
find 可以借助。cp 也可以用日期条件的。

看看这个吧:古老的系统,古老的文章,不过应该还管用。
http://www.chinaunix.net/jh/4/310686.html

服务器的管理,在 chinaunix 上面的资料还是很多很多的。
参考技术B rsync -avz

如何将linux中mysql备份恢复

一般是即时备份。做主从。或者是每天增量备份。
本文是在linux下,mysql 4.1.14版本下测试的,经过适当修改可能适合mysql 4.0,5.0及其其他版本.

本文适合于没有启动复制功能的mysql,如果启动了复制,可能不需要采取这种备份策略或者需要修改相关参数.

每个人的备份策略都可能不同,所以请根据实际情况修改,做到举一反三,不要照搬照抄,可能会造成不必要的损失.

希望你明白这个脚本要干什么工作!

脚本描述

每7天备份一次所有数据,每天备份binlog,也就是增量备份.

(如果数据少,每天备份一次完整数据即可,可能没必要做增量备份)

作者对shell脚本不太熟悉,所以很多地方写的很笨 :)

开启 bin log

在mysql 4.1版本中,默认只有错误日志,没有其他日志.可以通过修改配置打开bin log.方法很多,其中一个是在/etc/my.cnf中的mysqld部分加入:

[mysqld]
log-bin

这个日志的主要作用是增量备份或者复制(可能还有其他用途).

如果想增量备份,必须打开这个日志.

对于数据库操作频繁的mysql,这个日志会变得很大,而且可能会有多个.

在数据库中flush-logs,或者使用mysqladmin,mysqldump调用flush-logs后并且使用参数delete-master-logs,这些日志文件会消失,并产生新的日志文件(开始是空的).

所以如果从来不备份,开启日志可能没有必要.

完整备份的同时可以调用flush-logs,增量备份之前flush-logs,以便备份最新的数据.

完整备份脚本

如果数据库数据比较多,我们一般是几天或者一周备份一次数据,以免影响应用运行,如果数据量比较小,那么一天备份一次也无所谓了.

#!/bin/sh

BakDir=/backup/mysql
LogFile=/backup/mysql/mysqlbak.log

DATE=`date +%Y%m%d`

echo " " >> $LogFile
echo " " >> $LogFile
echo "-------------------------------------------" >> $LogFile
echo $(date +"%y-%m-%d %H:%M:%S") >> $LogFile
echo "--------------------------" >> $LogFile

cd $BakDir

DumpFile=$DATE.sql
GZDumpFile=$DATE.sql.tgz

mysqldump --quick --all-databases --flush-logs
--delete-master-logs --lock-all-tables
> $DumpFile

echo "Dump Done" >> $LogFile

tar czvf $GZDumpFile $DumpFile >> $LogFile 2>&1

echo "[$GZDumpFile]Backup Success!" >> $LogFile

rm -f $DumpFile

#delete previous daily backup files:采用增量备份的文件,如果完整备份后,则删除增量备份的文件.
cd $BakDir/daily

rm -f *

cd $BakDir

echo "Backup Done!"

echo "please Check $BakDir Directory!"

echo "copy it to your local disk or ftp to somewhere !!!"

ls -al $BakDir
上面的脚本把mysql备份到本地的/backup/mysql目录,增量备份的文件放在/backup/mysql/daily目录下.

注意:上面的脚本并没有把备份后的文件传送到其他远程计算机,也没有删除几天前的备份文件:需要用户增加相关脚本,或者手动操作.

增量备份

增量备份的数据量比较小,但是要在完整备份的基础上操作,用户可以在时间和成本上权衡,选择最有利于自己的方式.

增量备份使用bin log,脚本如下:

#!/bin/sh

#
# mysql binlog backup script
#

/usr/bin/mysqladmin flush-logs

DATADIR=/var/lib/mysql
BAKDIR=/backup/mysql/daily

###如果你做了特殊设置,请修改此处或者修改应用此变量的行:缺省取机器名,mysql缺省也是取机器名
HOSTNAME=`uname -n`

cd $DATADIR

FILELIST=`cat $HOSTNAME-bin.index`

##计算行数,也就是文件数
COUNTER=0
for file in $FILELIST
do
COUNTER=`expr $COUNTER + 1 `
done

NextNum=0
for file in $FILELIST
do
base=`basename $file`
NextNum=`expr $NextNum + 1`
if [ $NextNum -eq $COUNTER ]
then
echo "skip lastest"
else
dest=$BAKDIR/$base
if(test -e $dest)
then
echo "skip exist $base"
else
echo "copying $base"
cp $base $BAKDIR
fi
fi
done

echo "backup mysql binlog ok"
增量备份脚本是备份前flush-logs,mysql会自动把内存中的日志放到文件里,然后生成一个新的日志文件,所以我们只需要备份前面的几个即可,也就是不备份最后一个.
因为从上次备份到本次备份也可能会有多个日志文件生成,所以要检测文件,如果已经备份过,就不用备份了.

注:同样,用户也需要自己远程传送,不过不需要删除了,完整备份后程序会自动生成.

访问设置

脚本写完了,为了能让脚本运行,还需要设置对应的用户名和密码,mysqladmin和mysqldump都是需要用户名和密码的,当然可以写在脚本中,但是修改起来不太方便,假设我们用系统的root用户来运行此脚本,那么我们需要在/root(也就是root用户的home目录)创建一个.my.cnf文件,内容如下

[mysqladmin]
password =password
user= root
[mysqldump]
user=root
password=password
注:设置本文件只有root可读.(chmod 600 .my.cnf )

此文件说明程序使用mysql的root用户备份数据,密码是对应的设置.这样就不需要在脚本里写用户名和密码了.

自动运行

为了让备份程序自动运行,我们需要把它加入crontab.

有2种方法,一种是把脚本根据自己的选择放入到/etc/cron.daily,/etc/cron.weekly这么目录里.
一种是使用crontab -e放入到root用户的计划任务里,例如完整备份每周日凌晨3点运行,日常备份每周一-周六凌晨3点运行.
参考技术A

前言

MySQL 5.6引入了GTID,每个事务都会产生一个GTID,我们可以通过验证主从GTID来验证主从数据的一致性。

为了叙述简便,定义一个量ALL_GTID: 表示某个数据库实例上 所有存在过的 或 将要存在的事务 的GTID(包括已经被purge掉的事务)。

在讨论数据库可用性的场景中, 当发生主备切换时, 需要进行数据补偿。通过比较主备的ALL_GTID,可以确定需要补偿多少数据:

    在实例存活的情况,可以在实例状态中查询ALL_GTID。

    在实例崩溃的情况,无法在实例状态中查询ALL_GTID。可以通过查询BINLOG中的Previous-GTIDs计算来获得ALL_GTID。

    下面列举与ALL_GTID相关的变量。

    与ALL_GTID相关的变量

    Previous-GTIDs

    Previous-GTIDs格式如下(环境为MySQL5.7,日志手动flush binary logs获得):

    查看新轮转出的BINLOG:


    下面为mysql-bin.00001中包含的GTID:

    请点击输入图片描述


    然后再次flush binary logs:

    请点击输入图片描述


    mysql-bin.00002中是没有任何GTID的。

    请点击输入图片描述


    综上Previous-GTIDs是本身这个BINLOG文件前面的所有BINLOG的集合。

    请点击输入图片描述

    全局变量中的GTID相关的变量

    请点击输入图片描述

    变量解释:

    gtid_executed 代表着server上所有事务执行产生的GTID(包含已经被purge的BINLOG中的GTID或者是手动set gtid_purged的GTID)。

    gtid_purged 代表着已经被purge到的GTID。gtid_purged是gtid_executed的子集。

    gtid_retrieved 是从机上relay_log中的GTID。

    ALL_GTID 的计算

    了解了GTID相关的变量之后,可以得到获得实例的All_GTID的集合的方法:

    对象

    方法

    存活的Master实例    gtid_executed    

    存活的Slave实例    gtid_executed和gtid_retrieved的并集    

    非存活Master实例    最后一个BINLOG文件的Previous-GTIDs + 最后一个BINLOG文件中所有的GTID    

    非存活Slave实例    最后一个BINLOG文件的Previous-GTIDs + 最后一个BINLOG文件中所有的GTID    

    在获得非存活实例中的ALL_GTID时,最后一个BINLOG文件中的GTID可能不连续(比如事务同时来自于本实例客户端和复制回放),所以需要扫描最后一个BINLOG文件。

    生产中我们使用Xtrabackup来产生一个 从实例 的流程如下:

    拉取备份,进行还原

    change master to

    set @@global.gtid_purged='xxx';

    set @@global.gtid_purged='xxx'; 的影响:

    将 从实例 的ALL_GTID手工置为xxx, 在通过GTID方式建立复制时不会出错.

    将更新Binlog中记录的Previous-GTIDs (由于Binlog不可改变, 将产生新的Binlog, 记录新的Previous-GTIDs).

    MySQL 5.7中set gtid_purged的行为变更

    问题描述

    回顾一下备份恢复的流程:

    拉取备份,进行还原

    change master to

    set @@global.gtid_purged='xxx';

    现象: 发现有一台MySQL 5.7的Slave服务器恢复后没有产生 正确的Previous-GTIDs。

    分析

    分析整个过程,解决问题应该分阶段进行手动模拟发现问题。以下为详细步骤:

    手工还原备份

    环境

    BINLOG数量,Previous-GTIDs状态

    Xtrabackup 2.4.2 & MySQL 5.6    1,空    

    Xtrabackup 2.4.2 & MySQL 5.7    1,空    

    Xtrabackup 2.2.9 & MySQL 5.6    1,空    

    Xtrabackup 2.2.9 & MySQL 5.7    1,空    

    可见: 恢复过程不会轮转BINLOG。

    验证change master和set gtid_purged在不同的MySQL版本中执行的差异

    环境

    BINLOG数量,Previous-GTIDs状态

    change master & MySQL 5.6    1,空    

    change master & MySQL 5.7    1,空    

    set gtid_purged & MySQL 5.6    2,正常    

    set gtid_purged & MySQL 5.7    1,空    

    可见: 执行set gtid_purged时不同版本的MySQL产生了差异

    验证

    对不同版本MySQL单独执行set @@global.gtid_purged='';语句。检查结果

    环境

    进行的操作

    BINLOG数量,Previous-GTIDs状态

    MySQL 5.7    reset master; set @@global.gtid_purged=”;    1,空    

    MySQL 5.6    reset master; set @@global.gtid_purged=”;    2,正常    

    结论

    参考: http://bugs.mysql.com/bug.php?id=75767

    官方解释: 在5.7版本中,执行SET GTID_PURGED语句后binlog_simple_gtid_recovery会给GTID_PURGED计算出一个错误的值。

    由于5.7中新增了存储GTID的表。所以5.7版本中set @@global.gtid_purged='';语句被改成只修改存放GTID的表。

    而5.6版本中会进行BINLOG轮转和向Previous_gtids_log_event中添加GTID。如果5.7需要产生和5.6相同结果的话,可以在SET GTID_PURGED语句后手动执行flush binary logs语句。

以上是关于linux下如何实现增量备份?的主要内容,如果未能解决你的问题,请参考以下文章

Linux下的rsync远程增量备份详解

win7系统下mysql如何增量备份

linux中mysql如何备份与恢复

Linux下的rsync远程增量备份详解

如何进行增量备份?

如何进行MongoDB自动备份增量备份和恢复