数据备份

对于现代网络来说,数据是无价的,需要好好维护,为了避免误删、误更等的发生,需要一个
数据备份的方案进行维护。

备份方式

mysql按照备份恢复方式分为逻辑备份和物理备份

  • 逻辑备份:是备份sql语句,在恢复的时候执行备份的sql语句实
    现数据库数据的重现。
  • 物理备份:就是备份数据文件了,比较形象点就是cp下数据文件,
    但真正备份的时候自然不是的cp这么简单。

mysql按照数据库的运行状态分为热备,冷备和温备

  • 热备:在数据库运行时,直接进行备份,对运行的数据库没有影响。
  • 冷备:在数据库停止运行的时候进行备份,这种备份方式最为简单,只需要拷贝数据库物理文件即可。
  • 温备:同样是在数据库运行的时候进行备份的,但对当前数据库的操作会产生影响。

备份方案

  • 1.mysqldump + mysqlbinlog
  • 2.xtrabackup
  • 3.lvm2快照+mysqlbinlog

mysqldump&mysqlbinlog(全量物理&增量逻辑)

mysqldump

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1.输出指定数据库的完整备份文件到指定路径
mysqldump -hhostname –uname –ppasswd database > path.sql

2.备份到远程数据库
mysqldump -hhostname –uname –ppasswd database | mysql –hhostname –ppasswd –C database

3.还原备份文件到某个sql的某个数据库
mysql -hhostname -uuser -ppwd databasename < /path.sql

4.还原压缩的备份文件到某个sql的某个数据库
https://www.jianshu.com/p/b77dfd6d998b

5.备份并压缩
mysqldump –h –u –p database | gzip > path

6.备份多个数据库
mysqldump –h –u –p --databases databases1 2 3 > path.sql

7.备份数据库某些表
mysqldump –h –u –p databasename table1 2 3 > path.sql

8.仅备份数据结构
mysqldump -no-data –h –u –p databasename table1 2 3 > path.sql

9.备份所有数据库
mysqldump –all-databases > path.sql

简单linux脚本备份

  • 1.脚本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    touch mysql_backup.sh
    vim mysql_backup.sh

    # this is a mysql database backup shell script
    hostname = ’10.167.218.161’
    database = ‘test’
    bppath =’/root/mysql_backup’
    data = $(date+%Y%m%d_%H%M%S)
    user="xxxx"
    password="xxxxx"
    mysqldump –h$hostname –u$user –p$password $database|gzip > $bppath/$database_$date_sql.gz
  • 2.定时任务
    把它加入定时任务crontab

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    1.启动定时任务
    service crond start|status|stop
    systemctl start crond
    # 查看config文件,可以看到定时规则
    cat /etc/cron
    # 添加定时任务
    crontab –e
    # 添加定时计划
    0 2 * * * /path/mysql_backup.sh
    # 查看当前定时任务
    crontab –l
    # 查看定时计划日志
    tail –f /var/log/cron

mysqlbinlog

进行增量备份,备份二进制日志,将最后操作的二进制日志备份

1
2
3
4
5
6
cd /var/lib/mysql
# 查看最新的binlog
mysqlbinlog binlog.000001
# 导出最新的增量
mysqlbinlog --start-position=639 --stop-position=835
/var/lib/mysql/bin-log.000003 > /backup/binlog-`date +%F_%T`.sql

方案

1.使用mysqldump全量复制

1
2
3
4
5
6
7
8
备份整个库
mysqldump --all-databases --lock-all-tables --flush-log 
--master-data=2 >/backup/`date +%F_%T` -all.sql
备份某一个库
mysqldump -uroot -p123456 --databases
test --lock-all-tables --flush-log -hlocalhost 
--master-data=2 >/backup/`date +%F_%T`-test.sql;
ls /backup/进行查看

2.使用mysqlbinlog增量复制

1
2
3
保护最后的二进制文件
mysqlbinlog --start-position=639 --stop-position=835
/var/lib/mysql/bin-log.000003 > /backup/binlog-`date +%F_%T`.sql

3.数据恢复

1
2
3
4
5
# 首先恢复mysqldump全量复制的某个库
mysql -uroot -pZhanghaowei1! < xxxxx.sql
# 再恢复从那时起的增量
mysql -uroot -pZhanghaowei1! < bin_log-xxxxx.sql
mysql -uroot -pZhanghaowei1! < bin_log-xxxxx.sql

xtrabackup

Xtrabackup是由percona提供的mysql数据库备份工具,据官方介绍,是一款
开源能够对innodb和xtradb数据库进行热备的工具。

特点:

  • 1.备份过程快速、可靠
  • 2.备份过程不会打断正在执行的事务
  • 3.能够基于压缩等功能节约磁盘空间和流量
  • 4.自动实现备份检验
  • 5.还原速度快

安装

1
2
3
4
yum installpercona-xtrabackup-2.2.3-4982.el6.x86_64.rpm -y
创建最小权限备份用户
grant reload,lock tables,replicationclient on *.* to
'fulanqi'@'localhost' identified by '123';

完全备份

1
innobackupex --user=fulanqi --password=123 /backup/

增量备份

1
2
innobackupex --user=fulanqi --password=123 --incremental 
/backup/--incremental-basedir=/backup/binlog-`date +%F_%T`.sql

数据恢复

  • 数据准备
    一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中
    可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此
    ,此时数据文件仍处理不一致状态。“准备”的主要作用正是通过回滚未提交
    的事务及同步已经提交的事务至数据文件也使得数据文件处于一致性状态

  • 准备(prepare)增量备份与整理完全备份有着一些不同,尤其要注意的是:

    • 1.需要在每个备份(包括完全和各个增量备份)上,将已经提交的事务进行“
      重放”。“重放”之后,所有的备份数据将合并到完全备份上。
    • 2.基于所有的备份将未提交的事务进行“回滚”。
      1
      2
      3
      4
      全量
      innobackupex --apply-log --redo-only 全量路径
      增量
      # innobackupex --apply-log --redo-only BASE-DIR--incrementaldir=增量路径
  • 数据恢复
    这时候所有备份数据都在全量路径

    1
    innobackupex --copy-back 全量路径

python&xtrabackup

采用每周一0点进行一次全备,每日0点进行增备,一星期为一个周期。
如要恢复到某个时间点的数据,只需要找到还原到时间点当天的增量备份,然后再结合binlog日志进行恢复。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import commands
import base64
import datetime
import os
#------------自定义变量-----------
#备份数据库账号 bkUser='bkuser'
#备份数据库账户的密码,需要base64加密 bkPasswd='passwd'
#备份目录 bkDir='/data/backup'
#备份文件传给异地服务器的系统账号 tarUser='user'
#异地服务器 tarHost='ip'
#异地服务器的备份路径 ip tarBkDir=''

#---------------------------------
oneday=datetime.timedelta(days=1)
twoday=datetime.timedelta(days=2)
today=datetime.date.today()
formattedYesterday=(today-oneday).strftime('%Y%m%d')
formattedBeforeYesterday=(today-twoday).strftime('%Y%m%d')
week=datetime.datetime.now().weekday()
nowTime=str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))

def installXtrabackup():
commands.getstatusoutput('mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup')
commands.getstatusoutput('mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.backup')
commands.getstatusoutput('wget -O/etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo')
commands.getstatusoutput('wget -O/etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo')
commands.getstatusoutput('yum install -y http://www.percona.com/downloads/percona-release/redhat/0.1-6/percona-release-0.1-6.noarch.rpm')
commands.getstatusoutput('yum install -y percona-xtrabackup-24')

def copyFull():
print('---全备开始时间---:'+nowTime)
fileName='full_'+ formattedYesterday
bkFulCmd='innobackupex --no-timestamp /data/backup/%s -u%s -p%s'%(fileName,bkUser,base64.decodestring(bkPasswd))
commands.getstatusoutput(bkFulCmd)
print('---全备结束时间---:'+nowTime)
return fileName

def copyIncrement(file):
print('---增备开始时间---:'+nowTime)
fileName='rec_' + formattedYesterday
bkRecCmd='innobackupex --no-timestamp --incremental /data/backup/%s --incremental-basedir=/data/backup/%s -u%s -p%s'%(fileName,file,bkUser,base64.decodestring(bkPasswd))
commands.getstatusoutput(bkRecCmd)
print('---增备结束时间---:'+nowTime)
return fileName

def packBackup():
print('---打包开始时间---:'+nowTime)
os.chdir(bkDir)
os.chdir('..')
tarCmd='tar -cvf backup_%s.tar backup/'%(formattedYesterday)
commands.getstatusoutput(tarCmd)
commands.getstatusoutput('rm -rf /data/backup')
print('---打包结束时间---:'+nowTime)

def isCopyFulRec():
if os.path.exists(bkDir) == 0:
copyFull()
else:
dirlist = os.listdir(bkDir)
if dirlist:
print(dirlist)
tagFul = 'full'
tagRec = 'rec'
fileName = []
for i in dirlist:
if tagFul in i:
fileName.append(1)
elif tagRec in i:
fileName.append(2)
else:
fileName.append(0)

if 2 in fileName:
copyIncrement('rec_'+formattedBeforeYesterday)
elif 1 in fileName:
copyIncrement('full_'+ formattedBeforeYesterday)
else:
copyFull()
else:
copyFull()

def scpTarget():
print('---传包开始时间---:'+nowTime)
os.chdir(bkDir)
os.chdir('..')
tarName='backup_%s.tar'%formattedYesterday
scpCmd='scp %s %s@%s'%(tarName,tarUser,tarHost)
commands.getstatusoutput(scpCmd)
rmCmd='rm -rf %s'%tarName
commands.getstatusoutput(rmCmd)
print('---传包结束时间---:'+nowTime)


if __name__ == "__main__":
installXtrabackup()
if week==0:
copyFull()
packBackup() #打包
# 传到备份服务器
scpTarget()
else:
isCopyFulRec()

参考链接

mysql三种备份方案
MySQL常用备份方案

分享到