1.数据库管理员的两大工作核心
1.1.能够让数据安全得到保护
所谓的数据安全,最容易被人误以为是只有数据丢失,其实还包括数据被脱库、泄密等方面。
1.2.能7*24小时提供服务
数据库具备7*24小时提供服务的能力,是数据库管理员的重要职责。
2.全量备份和增量备份
2.1.全量备份的概念
全量数据就是数据库中所有的数据(或某一个库的全部数据);全量备份就是把数据库中所有的数据进行备份。
备份数据库中所有库的所有数据:
mysqldump -B --master-data=2 --single-transaction -A |gzip >/opt/all.sql.gz
备份oldboy一个库中所有数据:
mysqldump -B --master-data=2 --single-transaction oldboy |gzip >/opt/oldboy.sql.gz
2.2.增量备份的概念
增量数据就是指上一次全量备份数据之后到下一次全量备份之前数据库所更新的数据。在使用mysqldump命令做全备时,增量数据就是MySQL的binlog日志,因此,对binlog日志的备份在此处就可以称为增量备份,当然,有些工具本身就可以实现全量以及增量数据备份,例如Xtrabackup。
2.3.全量与增量如何结合备份
2.3.1.按天全备与增量备份数据
周一00点全量备份 | 周二00点全量备份 | 周三00点全量备份 | ...... |
---|---|---|---|
01.sql.gz | 02.sql.gz | 03.sql.gz | ...... |
周一增量备份 | 周二增量备份 | 周三增量备份 | ...... |
mysql-bin.000021、...... | mysql-bin.000035、...... | mysql-bin.000049、...... | ...... |
按天全备的特点:
1、优点:恢复数据时需要的数据文件数量少,恢复时间短,维护成本低。
2、缺点:每天一个全备,占用空间多,占用系统资源多,经常备份会影响用户体验。
中小企业用得最多的策略就是按天全备,然后根据空间情况保留全备份数,例如仅保留7天内的备份数据,如果企业数据很重要,则可以使用磁带机等设备留存一年以上的备份数据。
binlog增量的清理可以通过在my.cnf中配置“过期清理天数”的相关参数(expire_logs_days=7)来实现,例如保留7天内的binlog日志,理论上如果每天进行全备,那么binlog只要保留1天的。
2.3.2.按周全备与增量备份数据
每周一00点全量备份 | |||
---|---|---|---|
01.sql.gz | |||
周一增量备份 | 周二增量备份 | 周三增量备份 | 一直到下周日增量备份 |
mysql-bin.000021、...... | mysql-bin.000035、...... | mysql-bin.000049、...... | ...... |
按周全备的特点:
1、优点:每周仅有一个完整备份,因此占用磁盘总空间小,占用系统资源少,备份次数少,用户体验好一些。
2、缺点:恢复时数据文件多,导致恢复麻烦,维护成本高,恢复时间长。
大型企业由于数据量特别大,每天全备时间太长,因此有可能会采用周备的策略,这样不仅有利于节省数据存储空间而且不会影响用户访问数据库的体验。
3.MySQL常用的备份方式
MySQL备份的常用方式有逻辑备份和物理备份。
3.1.逻辑备份方式
3.1.1.逻辑备份
MySQL的逻辑备份其实就是使用MySQL自带的mysqldump命令或其他相关工具,把MySQL数据以SQL语句的形式导出或备份成文件。在恢复的时候则通过执行mysql恢复命令(或source等)将存储的SQL语句文件数据还原到MySQL数据库中。
实现逻辑备份的常用工具为MySQL自带的mysqldump命令,备份所有库:
mysqldump -A -B --master-data=2 --single-transaction |gzip >/opt/all.sql.gz
恢复数据库的方法之一为:
zcat opt/all.sql.gz|mysql
使用此种逻辑备份方式进行全量备份后的增量数据就是数据库记录的binlog日志文件,那么,如何增量恢复binlog日志呢?mysqlbinlog工具可以把binlog日志转换成SQL语句,然后通过mysql恢复命令(或source等)将SQL语句还原到MySQL数据库中。
恢复增量数据:
mysqlbinlog mysql-bin.000008 mysql-bin.000009 >bin.sql #将binlog文件解析为SQL语句
mysql <bin.sql #恢复到数据库
3.1.2.逻辑备份的特点
逻辑备份的优点为操作简单、方便、可靠,并且备份的数据可以跨平台、跨版本、甚至跨软件、跨操作系统,还可以实现分库分表备份;逻辑备份也有一定的缺点,例如,备份速度比物理备份慢、恢复的效率也不是特别高等。
3.1.3.逻辑备份的常用工具
mysqldump是MySQL官方自带的最常用的逻辑备份工具,还能实现分表分库备份,还有一个mydumper工具,它是一个在GPL许可下发布的高性能MySQL备份和恢复工具集。
3.1.4.逻辑备份的企业应用场景
适用于数据量不是特别大的场景,打包前不大于30GB的数据库数据,30GB的值主要是考虑备份效率的问题,以及管理员使用复杂度的平滑。不过,在跨版本、跨软件升级或迁移数据的时候,此时物理备份一般就不能使用。
3.2.物理备份方式
3.2.1.物理备份
3.2.1.1.冷备方法
MySQL的物理备份方法之一是使用cp、rsync、tar、scp等复制工具把MySQL数据文件复制成多份,由于在备份期间数据仍然有写入操作,所以,直接复制的备份方式会引起数据丢失。另外在恢复数据库时,对新数据库的路径、配置也有要求,一般要和原库的配置保持一致(版本、路径、配置尽可能一样)。
为了确保备份期间数据的一致性,可以选择人工停库或者锁库后再进行物理复制,而这在生产环境中一般是不允许的,除非是可以申请停机或锁表时间,所以使用传统Linux命令复制工具还是比较粗的冷备份方式,应避免使用。
一般在进行大规模数据库迁移时,先停库,然后物理迁移,这样做是很有效率的方案。
3.2.1.2.热备方法
除了在Linux命令行通过命令直接复制MySQL数据文件之外,还有一些其他的第三方的开源或商业物理热备份工具,如Xtrabackup。使用这个工具可以实现物理全备及增量备份。
3.2.2.物理备份的特点
物理备份的优缺点正好与逻辑备份相反,因此在企业里应根据需求,互补使用。
1、优点:速度快,效率高。
2、缺点:不容易跨平台、跨版本、跨软件、跨操作系统,可以实现分库分表备份,但恢复时会麻烦很多,软件的使用也比较复杂一些。
3.2.3.物理备份的常用工具或方法
Linux下冷备份工具为cp、tar,备份时需要锁表或者停库以确保数据的一致性;开源的热备份(基于InnoDB)工具则是Xtrabackup。
3.2.4.物理备份的企业应用场景
数据库总数据量超过30GB的,可使用Xtrabackup热备工具进行备份,以提升效率。
可以选择在数据库的从库上进行备份,备份时停止SQL线程应用数据到数据库,然后通过cp或tar打包备份,这也是一种不错的冷备方案,不会影响数据库的服务。
3.3.物理备份与逻辑备份的区别
物理备份与逻辑备份的对比:
逻辑备份 | 物理备份 | |
---|---|---|
备份原理 | 以SQL语句的形式 | 直接复制磁盘物理文件或其他非SQL语句方式的备份 |
相关命令 | mysqldump、mysql、mysqlbinlog | cp、rsync、tar、scp、Xtrabackup(热备) |
备份要求 | 需要锁表但不需要停库。锁表会影响数据库更新,InnoDB引擎可以不锁表,而采用事务备份方案 | 冷备需要锁表或停机,热备不需要锁表(仅事务引擎,例如InnoDB)或停机 |
配置特点 | 恢复时与系统版本、库的配置基本版本无关 | 物理复制需要系统、配置、版本尽可能地一致 |
性能特点 | 速度慢 | 速度快 |
方便性考虑 | 安全、易掌握、容易控制,一般不会丢失数据 | 冷备简单,但应用场景少,热备工具操作复制一些,较难掌握 |
4.逻辑备份的企业级应用
4.1.中小企业的MySQL备份实战
4.1.1.中小企业全备备份策略与应用
中小企业一般会采用逻辑备份,常用的工具就是mysqldump命令,备份的策略一般是每日进行全量备份,备份会选择在数据库业务流量低估时执行,备份时可以锁表或者采用事务方式备份。
简单的备份脚步:
vim bak.sh
#!/bin/bash
export PATH=/application/mysql/bin:/usr/local/bin:/sbin:/bin:/usr/bin
bak_path=/server/backup
[ ! -d $bak_path ] && mkdir -p $bak_path #若备份路径不存在则创建
mysqldump -B -A --master-data=2 |gzip >$bak_path/${file_name}.sql.gz #如果仅为innodb引擎,则可以再加上--single-transaction参数
rsync -az $bak_path/ rsync_backup@172.16.1.31::mysql/ --password-file=/etc/rsync.password
#备份完成后立刻推送至备份服务器,需要提前部署rsync服务
find $bak_path/ -type -f -name "*.sql.gz" -mtime +7|xargs rm -f #删除本地的7天备份
稍微复杂点的脚步:
vim bak.sh
#!/bin/bash
export PATH=/application/mysql/bin:/usr/local/bin:/sbin:/bin:/usr/bin
bak_path=/server/backup
[ ! -d $bak_path ] && mkdir -p $bak_path #若备份路径不存在则创建
if [ $(date +%w) -eq 6 ] #如果时间为周六,则
then
file_name=bak_$(date +%w_%F) #将备份文件名改为周和日期,目的是在备份服务器上保留每周六的数据
else
file_name=bak_$(date +%F) #否则,备份文件名为日期
fi
mysqldump -B -A --master-data=2 |gzip >$bak_path/${file_name}.sql.gz
md5sum $bak_path/${file_name}.sql.gz >$bak_path/${file_name}.flag #做md5指纹的目的是用于未来检测备份及传输结果是否正常
rsync -az $bak_path/ rsync_backup@172.16.1.31::mysql/ --password-file=/etc/rsync.password
#备份完成后立刻推送至备份服务器,需要提前部署rsync服务
find $bak_path/ -type -f -name "*.sql.gz" -mtime +7|xargs rm -f #删除本地的7天备份
配置定时任务,使其每日0点执行脚本:
crontab -e
bak mysql for oldboy at 20200515
00 00 * * * /bin/sh /server/scripts/bak.sh &>/dev/null
保留最近7天的所有备份,同时保留每周六的全部备份:
find /server/backup/ -type f -name "bak_*" -mtime +7 ! -name "bak_6*"
find /server/backup/ -type f -name "bak_*" -mtime +7 ! -name "bak_6*" |xargs rm -f
4.1.2.全备的数据何时可以派上用场
使用mysqldump全备的数据什么时候可以派上用场:
1、迁移或者升级数据库时。
2、增加从库时。
3、人为执行DDL、DML语句破坏数据库数据时(此时若使用主从库就会无法防止数据丢失,因为所有库都会执行破坏语句)。
4、跨机房灾备时,此时需要将全备份复制到异地。
若是因为硬件或删除物理文件导致数据库故障,就不需要用备份数据恢复了,可以直接把主库关闭,在从库上配置好VIP等配置后,启动从库提供服务即可。
4.1.3.中小企业增量备份策略
中小企业增量备份就是备份binlog文件,在MySQL没有主从复制功能或主从复制功能不完善的时候,我们就曾采取定时或实时推binlog文件的方法。例如每分钟推一次binlog到备份服务器上,或者通过mysqlbinlog参数read-from-remote-server,在其他服务器上远程读取binlog。
但是这类方法都不是最佳的,因为有可能会丢失数据。比较好的binlog增量备份或MySQL备份方法就是为MySQL数据库配置异机主从复制功能(实时复制功能),即binlog会被实时地发送到从服务器上,这样效果才是最好的。当然,也要相应地在主从复制的从库上实现全备。
4.1.4.备份binlog增量文件何时可以派上用场
当需要完整恢复数据库数据的时候,就会需要binlog增量恢复。
4.1.5.企业里MySQL备份策略选择
大多数中小企业的数据库环境都为一主多从,因此,可采取在一个从库服务器上专门做全量以及增量备份(需要开启从库记录binlog日志功能),至于备份方法,采用mysqldump、Xtrabackup均可。
4.2.中小企业MySQL增量恢复案例
完整恢复数据库数据需要具备的条件:
1、具备全量备份(mysqldump)。
2、除全量备份以外,还有全量备份之后产生的所有binlog增量日志。
模拟0点开始对数据库oldboy数据进行全备:
mysqldump -B --master-data=2 --single-transaction oldboy|gzip >/data/backup/oldboy_$(date +%F).sql.gz
模拟0点全备后用户继续写入数据:
mysql -e "use oldboy;insert into test values(6,'bingbing');"
mysql -e "use oldboy;insert into test values(7,'xiaoting');"
模拟上午10点管理员删除oldboy数据库:
mysql -e "drop database oldboy;show databases;"
恢复前准备,移走所有binlog增量文件,防止二次破坏,并确认是否有全备:
cp -a /application/mysql/data/mysql-bin.* /data/backup/
开始恢复:
1、停止数据库对外访问。因为是通过drop命令删除数据库的,后面不会有写入操作,因此,可以不用额外停止写入。但如果是因为update导致的数据破坏,最好是停库处理或对外停止写入。这里采用iptables防火墙屏蔽所有应用程序的写入:
iptables -I INPUT -p tcp --dport 3306 ! -s 172.16.1.51 -j DROP #非172.16.1.51禁止访问数据库3306端口。
2、解压全备的数据:
gzip -cd oldboy_2020-05-19.sql.gz >oldboy.sql
3、解析binlog文件增量数据:
sed -n '22p' oldboy.sql
从代码里可以看到,要从mysql-bin.000004文件的7181位置点开始恢复增量数据:
mysqlbinlog -d oldboy mysql-bin.000004 --start-position=7181 -r bin.sql
恢复后面的所有binlog文件:
mysqlbinlog -d oldboy mysql-bin.000005 mysql-bin.000006 -r bin1.sql
4、剔除误删除数据库的drop语句:
grep -w drop bin.sql #过滤drop单词的行。
sed -i '/drop database oldboy/d' bin.sql #删除drop数据库oldboy的语句。
恢复0点以前的全备数据:
mysql </data/backup/oldboy.sql #先恢复全备,即0点以前的备份
恢复增量备份:
mysql oldboy</data/backup/bin.sql #恢复增量文件
5.分库分表的生产备份策略
5.1.为什么要分库分表备份
全备命令把2个库备份成了一个备份文件:
mysqldump -B --master-data=2 --single-transaction oldboy mysql|gzip>/data/backup/all.sql.gz
在还原时,很多时候只需要还原一个库或者多个库的一个表,这个时候,整个备份文件就会很难拆分,给恢复也会带来麻烦。对于这种情况,最好是分库分表备份。
5.2.如何进行分库备份
最佳的方法就是从数据库中取出所有库名,然后对每个数据库执行一次备份。
分库备份的脚本:
vi fenku.sh
#!/bin/bash
export PATH=/application/mysql/bin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
bak_path=/server/backup/$(date +%F)
[ ! -d $bak_path ] && mkdir -p $bak_path
for dbname in `mysql -e "show databases"|sed '1,2d'|grep -v _schema` #取库名轮询备份
do
mysqldump -B --master-data=2 $dbname|gzip >$bak_path/${dbname}_$(date +%F).sql.gz #注意备份的名字
done
5.3.如何进行分表备份
分表备份比分库更细,实际上就是先取一个库名,然后循环读取该库里的表进行备份,备份完之后,再取下一个库名,继续循环库里的所有表进行备份,知道所有库里的所有表都备份完毕。
分表备份的脚本:
vi fenbiao.sh
#!/bin/bash
export PATH=/application/mysql/bin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
bak_path=/server/backup/$(date +%F)
[ ! -d $bak_path ] && mkdir -p $bak_path
for dbname in `mysql -e "show databases"|sed '1,2d'|grep -v _schema`
do
for tablename in `mysql -e "show tables from $dbname;"|sed '1d'`
do
mysqldump -B --master-data=2 $dbname$tablename|gzip >$bak_path/${dbname}_${tablename}_$(date +%F).sql.gz
done
done
6.MySQL生产常用备份架构方案
在中小公司一般比较常用的做法是,每日0点执行全备任务,先把数据按照日期备份到数据库本地,然后推送到数据库备份服务器,由于本地空间有限,因此本地仅保留3-7日的全备。
如果有备用的服务器资源可用,那么最好通过主从同步的方式进行备份,这样即使物理机损坏了也可以很快地切换到新服务器(还可以HA自动切换),但是主从复制的缺点是不能解决错误执行SQL语句的问题。
因此,我们一般会在某一台不对外提供业务的从库上使用mysqldump或Xtrabackup来进行定时备份。这里有个需要特别注意的地方,用于备份从库的二进制日志记录功能必须打开。