博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
XtraBackup应用说明(支持TokuDB)
阅读量:5943 次
发布时间:2019-06-19

本文共 24964 字,大约阅读时间需要 83 分钟。

背景:

      关于物理备份工具xtrabackup的一些说明可以先看之前写过的文章说明:和,本篇文章将介绍xtrabackup在使用中的注意事项和如何全量、增量备份和恢复,包含TokuDB的备份(感谢的推荐)。由于物理备份消耗的空间比较大,所以在工作中一直使用进行备份,通过逻辑备份虽然空间使用上又很大改善,但是由于还原的时候需要消耗很长时间才能使用,也非常令人头疼。现在准备在生产环境中使用XtraBackup,记录使用中的一些注意事项。

安装:

环境:

XtraBackup版本为:2.4系统版本:14.04、16.04MySQL版本:5.7.16

说明:因为生产环境中有使用到TokuDB引擎,而Percona版本的XtraBackup不支持对TokuDB的备份,所以不能使用官方的版本。不过有人基于官方版本进行了修改,支持Tokudb的备份,下载地址:,作者是BohuTANG。编译安装:

① 下载:

git clone https://github.com/XeLabs/tokudb-xtrabackup.git

② 安装:

apt-get install build-essential flex bison automake autoconf \   libtool cmake libaio-dev mysql-client libncurses-dev zlib1g-dev \   libgcrypt11-dev libev-dev libcurl4-gnutls-dev vim-common

③ 编译安装

#程序目录mkidr /usr/local/xtrabackup_dir/#编译cd tokudb-xtrabackupcmake .  -DBUILD_CONFIG=xtrabackup_release  -DWITH_BOOST=extra/boost/boost_1_59_0.tar.gz  -DWITH_MAN_PAGES=OFF  -DCMAKE_INSTALL_PREFIX=/usr/local/xtrabackup_dir/make VERBOSE=1make -j8#安装make install

安装成功之后,文件里的信息如下:

/usr/local/xtrabackup_dir/bin# ls -lh总用量 200Mlrwxrwxrwx 1 root root   10  8月 21 11:51 innobackupex -> xtrabackup-rwxr-xr-x 1 root root 5.2M  8月 21 11:22 xbcloud-rwxr-xr-x 1 root root 3.0K  8月 21 11:17 xbcloud_osenv-rwxr-xr-x 1 root root 5.0M  8月 21 11:22 xbcrypt-rwxr-xr-x 1 root root 5.1M  8月 21 11:22 xbstream-rwxr-xr-x 1 root root 185M  8月 21 11:32 xtrabackup

因为包含了一些符号信息和调试信息,xtrabackup文件很大,通过strip进行剥离:

strip xtrabackup

备份使用说明:

对于上面编译好的XtraBackup,对于备份TokuDB引擎有个限制,即不能指定tokudb_data_dir变量,必须使用默认参数。并且MySQL5.7也已经把TokuDB文件放入到对应的数据库文件夹中。

备份策略:

.每周日进行全量备份,周一至周六进行基于全量备份的增量备份。这样即使还原周四的备份,也只要prepare全量和周四增量的备份即可,不需要把周四之前的增量全部apply。.备份文件不存本地,直接远程保存到备份服务器。.备份一个从库,还原完成直接当从库来使用。

环境:

MySQL A服务器(备份)XtraBackup B备份服务器MySQL C服务器(还原)

MySQL配置文件中配置目录的相关参数:日志文件(error log、binlog)最好别放数据目录里。

innodb_undo_directory   = /var/lib/mysql/undolog/tokudb_log_dir          = /var/lib/mysql/tokudb_log

注意:三台服务器上最好都装上XtraBackup,并且A和C的MySQL的配置文件配置的目录需要一致,如:undolog目录、tokudb目录等。关于备份相关的命令可以看之前写的文章,本文的备份命令如下:

1)全量备份,每周日进行

/usr/local/xtrabackup_dir/bin/xtrabackup --defaults-extra-file=/etc/mysql/xtrabackup.cnf --datadir=/var/lib/mysql --host=A --no-timestamp --slave-info --safe-slave-backup --ftwrl-wait-query-type=all --history --backup --parallel=5 --compress --compress-threads=3 --stream=xbstream --encrypt=AES256 --encrypt-key-file=/opt/bin/keyfile --encrypt-threads=3 | ssh B "/usr/local/xtrabackup_dir/bin/xbstream -x -C /data/"

解释:通过实际情况指定需要的,压缩加密打包到远程服务器,并在远程服务器解包到指定的目录。

--defaults-extra-file :该选项指定了在标准defaults-file之前从哪个额外的文件读取MySQL配置,必须在命令行的第一个选项的位置。一般用于存备份用户的用户名和密码的配置文件。--datadir :backup的源目录,mysql实例的数据目录。从my.cnf中读取,或者命令行指定。--host:该选项表示备份数据库的地址。--no-timestamp:该选项可以表示不要创建一个时间戳目录来存储备份,指定到自己想要的备份文件夹。--slave-info:该选项表示对slave进行备份的时候使用,打印出master的名字和binlog pos,同样将这些信息以change 。master的命令写入xtrabackup_slave_info文件。--safe-slave-backup:该选项表示为保证一致性复制状态,这个选项停止SQL线程并且等到show status中的slave_open_temp_tables为0的时候开始备份,如果没有打开临时表,bakcup会立刻开始,否则SQL线程将关闭直到没有打开的临时表。如果slave_open_temp_tables在--safe-slave-backup-timeount(默认300秒)秒之后不为0,从库sql线程会在备份完成的时候重启。--ftwrl-wait-query-type:该选项表示获得全局锁之前允许那种查询完成,默认是ALL,可选update。--history:该选项表示percona server 的备份历史记录在percona_schema.xtrabackup_history表。--backup:创建备份并且放入--target-dir目录中。--parallel:指定备份时拷贝多个数据文件并发的进程数,默认值为1。--compress:该选项表示压缩innodb数据文件的备份。--compress-threads:该选项表示并行压缩worker线程的数量。--stream:该选项表示流式备份的格式,backup完成之后以指定格式到STDOUT,目前只支持tar和xbstream。--encrypt:该选项表示通过ENCRYPTION_ALGORITHM的算法加密innodb数据文件的备份,目前支持的算法有ASE128,AES192,AES256。--encrypt-threads:该选项表示并行加密的worker线程数量。--encryption-key-file:该选项表示文件必须是一个简单二进制或者文本文件,加密key可通过以下命令行命令生成:openssl rand -base64 24。

在备份中,备份账号和密码存放在/etc/mysql/xtrabackup.cnf中,格式为:

[client]user=xtrabackuppassword=xtrabackup

生成加密key:

openssl rand -base64 24echo -n "5V05Dm+aFiRxZ6+sjfplK0K2YlbOplZn" > keyfile

该备份账号的权限:

>show grants for xtrabackup@localhost;+-------------------------------------------------------------------------------------------------------------------------+| Grants for xtrabackup@localhost                                                                                             |+-------------------------------------------------------------------------------------------------------------------------+| GRANT CREATE, RELOAD, PROCESS, SUPER, LOCK TABLES, REPLICATION CLIENT, CREATE TABLESPACE ON *.* TO 'xtrabackup'@'localhost' || GRANT SELECT, INSERT, CREATE ON `PERCONA_SCHEMA`.* TO 'xtrabackup'@'localhost'                                              |+-------------------------------------------------------------------------------------------------------------------------+

 2)增量备份:每周一至周六执行

/usr/local/xtrabackup_dir/bin/xtrabackup --defaults-extra-file=/etc/mysql/xtrabackup.cnf --datadir=/var/lib/mysql --host=A --no-timestamp --slave-info --safe-slave-backup --ftwrl-wait-query-type=all --history --backup --parallel=5  --compress --compress-threads=3 --stream=xbstream --encrypt=AES256 --encrypt-key-file=/opt/bin/keyfile --encrypt-threads=3 --incremental-lsn=NUM  | ssh B "/usr/local/xtrabackup_dir/bin/xbstream -x -C /data/1/

解释:

--incremental-lsn:该选项表示指定增量备份的LSN,与--incremental选项一起使用。

因为增量备份是根据全量备份(target_dir)来进行的,由于全量已经传输到备份服务器,本地不存备份,所以需要通过记录当时全量备份时候的LSN,再基于此LSN进行增量备份。

备份信息说明

1:因为从库开了多线程复制(slave_parallel_workers),但没开启GTID,而XtraBackup要求2者必须都开启,否则报错:

The --slave-info option requires GTID enabled for a multi-threaded slave.

所以在备份脚本里进行了设置:备份开始前先设置成单线程复制,结束之后设置成多线程;也可以直接开启GTID。

2:由于开启了--safe-slave-backup参数,在一定时间里(--safe-slave-backup-timeout),默认300秒,若slave_open_temp_tables参数大于0则会暂停Slave的SQL线程,等待到没有打开的临时表的时候开始备份,备份结束后SQL线程会自动启动。要是备份时间比较长,少不了报警短信的骚扰。因为我在还原该备份完成之后,会对其进行,就关闭了该参数进行备份。最终备份的命令如下:

1)全量备份

/usr/local/xtrabackup_dir/bin/xtrabackup --defaults-extra-file=/etc/mysql/xtrabackup.cnf --datadir=/var/lib/mysql --host=A --no-timestamp --slave-info --ftwrl-wait-query-type=all --backup --parallel=5 --compress --compress-threads=3 --stream=xbstream --encrypt=AES256 --encrypt-key-file=/opt/bin/keyfile --encrypt-threads=3 | ssh B "/usr/local/xtrabackup_dir/bin/xbstream -x -C /data/"

2)增量备份

/usr/local/xtrabackup_dir/bin/xtrabackup --defaults-extra-file=/etc/mysql/xtrabackup.cnf --datadir=/var/lib/mysql --host=A --no-timestamp --slave-info --ftwrl-wait-query-type=all --backup --parallel=5  --compress --compress-threads=3 --stream=xbstream --encrypt=AES256 --encrypt-key-file=/opt/bin/keyfile --encrypt-threads=3 --incremental-lsn=NUM  | ssh B "/usr/local/xtrabackup_dir/bin/xbstream -x -C /data/1/

注意:编译的xtrabackup只支持TokuDB的全量备份,不支持增量备份。

为了方便,把备份命令放到python里面去执行,定制成一个备份脚本:(备份服务器B上先创建好目录。MySQL A服务器上再执行脚本)

MySQL A服务器上的脚本:

#!/usr/bin/env python#-*- encoding:utf-8 -*-import osimport sysimport timeimport datetimeimport smtplibimport subprocessimport reimport MySQLdbfrom email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartfrom email.Utils import COMMASPACE, formatdatereload(sys)sys.setdefaultencoding('utf8')RETRIES = 1def retry_times(func):    def wrapped(*args, **kwargs):        global RETRIES        try:            return func(*args, **kwargs)        except Exception, err:            #重试次数            if RETRIES <= 10:                print "\n邮件发送重试第【%s】次\n" %RETRIES                RETRIES += 1                time.sleep(1)                if RETRIES == 10:                    print "\n重试10次,邮件发送失败,exit...\n"                    sys.exit()            return wrapped(*args, **kwargs)    return wrapped@retry_timesdef send_mail(to, subject, text, from_mail, server="localhost"):    message = MIMEMultipart()    message['From'] = from_mail    message['To'] = COMMASPACE.join(to)    message['Date'] = formatdate(localtime=True)    message['Subject'] = subject    message.attach(MIMEText(text,_charset='utf-8'))    smtp = smtplib.SMTP(server,timeout=3)    smtp.sendmail(from_mail, to, message.as_string())    smtp.close()def getDate():    today = datetime.datetime.now().strftime('%Y-%m-%d')    weekday = datetime.datetime.now().weekday()    return today,weekdaydef getMonDay(num):    monday = (datetime.date.today() - datetime.timedelta(days=num)).strftime("%Y-%m-%d")    return mondaydef getTime():    now = datetime.datetime.now().strftime('%H:%M:%S')    return nowdef getPath():    Path = os.path.realpath(os.path.dirname(__file__))    return Pathdef setSingleThread(conn):    queries = '''\STOP SLAVE;\START SLAVE UNTIL SQL_AFTER_MTS_GAPS;\SET @@GLOBAL.slave_parallel_workers = 0;\START SLAVE SQL_THREAD\'''    for query in queries.split(';'):        cursor = conn.cursor()#        print query        time.sleep(0.5)        cursor.execute(query)def setMultiThread(conn):    queries = '''\STOP SLAVE;\START SLAVE UNTIL SQL_AFTER_MTS_GAPS;\SET @@GLOBAL.slave_parallel_workers = 4;\START SLAVE SQL_THREAD\'''    for query in queries.split(';'):        cursor = conn.cursor()#        print query        time.sleep(0.5)        cursor.execute(query)def run_cmd(cmd):    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)    ret_str = p.stdout.read()    retval = p.wait()    return ret_strif __name__ == "__main__":    CWD = '/etc/mysql'    db_conf = os.path.join(CWD, 'xtrabackup.cnf')    conn = MySQLdb.connect(read_default_file=db_conf,host='localhost',port=3306,charset='utf8')    instance_name = 'Job'    local_host    = 'localhost'    remote_host   = 'C'    today,weekday = getDate()    weekday = weekday + 1    print "\n\n\n\n\n备份执行日期是:%s,  星期%s\n" %(today,weekday)#    today = '2017-08-20'#    weekday = 7    if weekday == 7:        setSingleThread(conn)        print("\033[0;32m set single thread replication sucess... \033[0m")        remote_backupfile = '/data/dbbackup_dir/job/%s/full_backup' %today        print remote_backupfile        print("\033[0;32m execute full backup... \033[0m")#--safe-slave-backup --safe-slave-backup-timeout=600        xtrabackup_fullbackup = '''/usr/local/xtrabackup_dir/bin/xtrabackup --defaults-extra-file=/etc/mysql/xtrabackup.cnf --datadir=/var/lib/mysql --host=%s --no-timestamp --slave-info --ftwrl-wait-query-type=all --backup --parallel=5 --compress --compress-threads=3 --stream=xbstream --encrypt=AES256 --encrypt-key-file=/opt/bin/keyfile --encrypt-threads=3 | ssh %s "/usr/local/xtrabackup_dir/bin/xbstream -x -C %s" ''' %(local_host,remote_host,remote_backupfile)        print "\n执行全量备份的命令:\n%s\n" %xtrabackup_fullbackup        res = run_cmd(xtrabackup_fullbackup)        print res        setMultiThread(conn)        print("\033[0;32m set multi thread replication sucess... \033[0m")        if res.find('completed OK!') > 0:            _point = re.compile(ur'.*(xtrabackup: The latest check point \(for incremental\): )\'([0-9]+\.?[0-9]*)\'*')            incremental_point = dict(_point.findall(res)).get('xtrabackup: The latest check point (for incremental): ')            f = open(os.path.join(getPath(),'incremental_point.txt'),'w')            f.write(incremental_point)            f.close()            if incremental_point:                subject = '%s【%s】全量物理备份成功' %(today,instance_name)                mail_list = ['zjy@dxyer.com']                send_mail(mail_list, subject.encode("utf8"), 'Sucess!', "XtraBackup@smtp.dxy.cn", server="smtp.host.dxy")            else :                subject = '%s【%s】全量物理备份获取lsn失败' %(today,instance_name)                mail_list = ['zjy@dxyer.com']                send_mail(mail_list, subject.encode("utf8"), res, "XtraBackup@smtp.dxy.cn", server="smtp.host.dxy")        else :            subject = '%s【%s】全量物理备份失败' %(today,instance_name)            mail_list = ['zjy@dxyer.com']            send_mail(mail_list, subject.encode("utf8"), res, "XtraBackup@smtp.dxy.cn", server="smtp.host.dxy")    else :        setSingleThread(conn)        print("\033[0;32m set single thread replication sucess... \033[0m")        print("\033[0;32m execute incremental backup... \033[0m")        monday = getMonDay(weekday)        remote_backupfile = '/data/dbbackup_dir/job/%s/%s' %(monday,weekday)#        print remote_backupfile        try:            f = open(os.path.join(getPath(),'incremental_point.txt'),'r')            incremental_point = f.read()            f.close()        except Exception,e:            incremental_point = None            print e        if incremental_point:#--safe-slave-backup --safe-slave-backup-timeout=600            xtrabackup_incrbackup = '''/usr/local/xtrabackup_dir/bin/xtrabackup --defaults-extra-file=/etc/mysql/xtrabackup.cnf --datadir=/var/lib/mysql --host=%s --no-timestamp --slave-info --ftwrl-wait-query-type=all --backup --parallel=5  --compress --compress-threads=3 --stream=xbstream --encrypt=AES256 --encrypt-key-file=/opt/bin/keyfile --encrypt-threads=3 --incremental-lsn=%s  | ssh %s "/usr/local/xtrabackup_dir/bin/xbstream -x -C %s"''' %(local_host,incremental_point,remote_host,remote_backupfile)            print "\n执行增量备份的命令:\n%s\n" %xtrabackup_incrbackup            res = run_cmd(xtrabackup_incrbackup)            print res            setMultiThread(conn)            print("\033[0;32m set multi thread replication sucess... \033[0m")            if res.find('completed OK!') > 0:                subject = '%s【%s】增量物理备份成功' %(today,instance_name)                mail_list = ['zjy@dxyer.com']                send_mail(mail_list, subject.encode("utf8"), 'Sucess!', "XtraBackup@smtp.dxy.cn", server="smtp.host.dxy")            else :                subject = '%s【%s】增量物理备份失败' %(today,instance_name)                mail_list = ['zjy@dxyer.com']                send_mail(mail_list, subject.encode("utf8"), res, "XtraBackup@smtp.dxy.cn", server="smtp.host.dxy")        else :                setMultiThread(conn)                print("\033[0;32m set multi thread replication sucess... \033[0m")                subject = '%s【%s】增量物理备份获取lsn失败' %(today,instance_name)                mail_list = ['zjy@dxyer.com']                send_mail(mail_list, subject.encode("utf8"), str(e) , "XtraBackup@smtp.dxy.cn", server="smtp.host.dxy")
View Code

备份服务器B上的脚本:

#!/usr/bin/env python#-*- encoding:utf-8 -*-import osimport sysimport timeimport datetimeimport commandsdef getDate():    today = datetime.datetime.now().strftime('%Y-%m-%d')    weekday = datetime.datetime.now().weekday()    return today,weekdaydef mkdir(path):    isExists=os.path.exists(path)    if not isExists:        os.makedirs(path)        print "创建成功!"    else:        print "文件夹存在!"if __name__ == "__main__":    today,weekday = getDate()    weekday = weekday + 1#    print today,weekday    if weekday == 7:#        today = '2017-08-20'        backup_path  = '/data/dbbackup_dir/'        instsance_names = ['test','test1','test2']        dir_names = ['full_backup','1','2','3','4','5','6']        for instsance_name in instsance_names:            for dir_name in dir_names:                dir_path = os.path.join(backup_path,instsance_name,today,dir_name)                mkdir(dir_path)    else :        print "只在周日执行..."
View Code

模拟全量备份,备份流程原理的信息如下:

1):fork 一个子线程进行redo log 的复制2):主线程进行ibd文件复制,直到ibd文件复制完3):SET GLOBAL =ON,它的作用是允许拿到checkpoint锁,此时TokuDB的checkpoint会一直block到该锁释放(执行前要把tokudb_checkpoint_on_flush_logs关掉),目的是防止拷贝TokuDB数据文件的过程中做sharp checkpoint(注意:由于不做checkpoint,TokuDB的日志文件会逐渐增多),从而导致数据文件内部不一致(已拷贝的文件被修改)4):LOCK TABLES FOR BACKUP1.禁止非innodb表更新2.禁止所有表的ddl优化点:1.不会关闭表2.不会堵塞innodb表的读取和更新,对于业务表全部是innodb的情况,则备份过程中DML完全不受损。5):开始并完成备份非InnoDB表和文件6):LOCK BINLOG FOR BACKUP,获取一致性位点1.禁止对位点更新的操作2.允许DDl和更新,直到写binlog为止。7):FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS,写binlog,不轮询。8):开始和完成备份TokuDB的undo和redo9):记录LSN最后的点,停止redo log的线程的备份10):解锁binlog和tables11):开始和完成备份TokuDB文件12):SET GLOBAL tokudb_checkpoint_lock=OFF,解锁TokuDB的checkpoint锁。

增量备份则读取全量备份时候记录的点位进行备份(脚本里把点位写入到了文件中)。备份服务器的目录如下:

# du -sch 2017-08-20/*4.0K    2017-08-20/14.0K    2017-08-20/24.0K    2017-08-20/34.0K    2017-08-20/44.0K    2017-08-20/54.0K    2017-08-20/633G    2017-08-20/full_backup33G    total

到此,备份大致的流程已经介绍完毕,那么接着继续介绍如何还原。

还原使用说明:

1:全量备份的还原

因为通过上面的备份脚本已经把备份文件传输到了备份服务器B中,后面的相关操作只要在备份服务器B和MySQL服务器C中进行。

1)从备份服务器B中,把备份传到MySQL服务器C中。如备份目录为full_backup

scp -r full_backup/ C:/data/dbbackup_dir/

2)在MySQL服务器C中进行解密、解压和prepare。解密的key需要和上面加密时候生成的key保持一致!解压需要安装qpress。

#解密:for i in `find . -iname "*\.xbcrypt"`; do /usr/local/xtrabackup_dir/bin/xbcrypt -d --encrypt-key-file=/data/keyfile --encrypt-algo=AES256 < $i > $(dirname $i)/$(basename $i .xbcrypt) && rm $i; done#解压for f in `find ./ -iname "*\.qp"`; do qpress -dT2 $f  $(dirname $f) && rm -f $f; done #prepare,需要执行2次,第1次回滚未提交和执行已提交的事务,第2次生成redo log,加快mysql启动时间。/usr/local/xtrabackup_dir/bin/xtrabackup --prepare --apply-log-only --use-memory=1G --target-dir=/data/dbbackup_dir/full_backup

备份文件说明:

root@db-test-xt:/data/dbbackup_dir/full_backup# ls -lh xtrabackup_*-rw-r--r-- 1 root root   27 Aug 22 10:28 xtrabackup_binlog_info-rw-r--r-- 1 root root   27 Aug 22 10:28 xtrabackup_binlog_pos_innodb-rw-r--r-- 1 root root  121 Aug 22 10:28 xtrabackup_checkpoints-rw-r--r-- 1 root root  687 Aug 22 10:27 xtrabackup_info-rw-r--r-- 1 root root 8.0M Aug 22 10:28 xtrabackup_logfile-rw-r--r-- 1 root root   83 Aug 22 10:24 xtrabackup_slave_info
xtrabackup_binlog_info:记录备份时的binlog点位,若有MyISAM存储引擎,以该点位准。xtrabackup_binlog_pos_innodb:记录备份时的binlog点位,用于InnoDB、XtraDB的点位记录。xtrabackup_checkpoints:记录备份模式(backup_type)以及放备份的起始位置beginlsn和结束位置endlsn等。xtrabackup_slave_info:备份从库时记录的CHANGE信息。xtrabackup_info:备份的具体信息,如备份命令、版本、开始结束时间、是否压缩、加密等信息。

经过上面的解密、解压、prepare之后,数据库的文件已经生成,现在需要做的就是把这些文件放到MySQL数据目录中。

3)还原,复制文件

注意:备份和还原的MySQL配置文件所配置的目录需要保持一致,如:undolog是否独立,tokudb必须不能指定目录,保证备份和还原MySQL目录的一致性。如果起来当一个从来服务则需要修改server_id。

1:复制文件到数据目录/data/dbbackup_dir# mv full_backup/* /var/lib/mysql/2:根据配置文件设置目录/var/lib/mysql# mkdir undolog/var/lib/mysql# mv undo00* undolog/3:修改权限/var/lib# chown -R mysql.mysql mysql/4:确定好目录没问题之后,就可以直接开启MySQL

如果MySQL已经正常启动,只需要执行start slave,不需要change就可以直接成为一个从服务。如果担心主从数据的一致性问题,可以通过来保证。

2:增量备份的还原

上面已经模拟进行了周日全量备份,现在模拟在上面的全量基础上进行的增量备份。在进行全量备份时的LSN已经写入到了文件incremental_point.txt中,该文件和备份脚本在同一级目录。

还是和全量备份一样,执行上面给出的定制备份脚本,如执行时间是周二,执行完后备份服务器的目录如下:

# du -sch 2017-08-20/*4.0K    2017-08-20/18.2G    2017-08-20/24.0K    2017-08-20/34.0K    2017-08-20/44.0K    2017-08-20/54.0K    2017-08-20/633G    2017-08-20/full_backup41G    total

可以看到增量备份目录是2,这里需要注意的是:真正的增量其实是对InnoDB的增量,而MyISAM和TokuDB还是直接拷贝文件的全量数据。可以通过增量备份打印出来的信息或则看增量备份的MyISAM、TokuDB的数据文件看出。

增量备份的备份流程和全量备份一样,可以直接看全量备份的说明即可,那么接着继续介绍如何进行增量+全量的还原。

因为通过上面的备份脚本已经把备份文件传输到了备份服务器B中,后面的相关操作只要在备份服务器B和MySQL服务器C中进行。

1)从备份服务器B中,把备份传到MySQL服务器C中。如备份目录为2

scp -r 2/ C:/data/dbbackup_dir/

2)在MySQL服务器C中进行解密、解压和prepare。解密的key需要和上面加密时候生成的key保持一致!解压需要安装qpress。

#解密:在full_backup和2目录里执行for i in `find . -iname "*\.xbcrypt"`; do /usr/local/xtrabackup_dir/bin/xbcrypt -d --encrypt-key-file=/data/keyfile --encrypt-algo=AES256 < $i > $(dirname $i)/$(basename $i .xbcrypt) && rm $i; done#解压:在full_backup和2目录里执行for f in `find ./ -iname "*\.qp"`; do qpress -dT2 $f  $(dirname $f) && rm -f $f; done
#prepare full_backup/usr/local/xtrabackup_dir/bin/xtrabackup --prepare --apply-log-only --use-memory=1G --target-dir=/data/dbbackup_dir/full_backup

这里需要注意全量备份的元数据中的信息(/data/dbbackup_dir)

# cat full_backup/xtrabackup_checkpoints backup_type = log-appliedfrom_lsn = 0to_lsn = 370623694056last_lsn = 370623694065compact = 0recover_binlog_info = 0# cat full_backup/xtrabackup_slave_info CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin-3306.000368', MASTER_LOG_POS=48441381;

基于全量备份的增量prepare,可以先删除全量备份目录下的ib_buffer_pool,不然会在prepare增量的时候报错,不过不影响后续操作。

xtrabackup: Can't create/write to file './ib_buffer_pool' (Errcode: 17 - File exists)[00] error: cannot open the destination stream for /ib_buffer_pool[00] Error: copy_file() failed.

接着应用增量备份

#prepare 2/usr/local/xtrabackup_dir/bin/xtrabackup --prepare --apply-log-only --use-memory=1G --target-dir=/data/dbbackup_dir/full_backup --incremental-dir=/data/dbbackup_dir/2

这里需要注意增量备份中元数据的信息(/data/dbbackup_dir),和全量备份中进行对比:

# cat 2/xtrabackup_checkpoints backup_type = incrementalfrom_lsn = 370623694056    #对应全量备份中的to_lsnto_lsn = 371913526149last_lsn = 371913526158compact = 0recover_binlog_info = 1# cat 2/xtrabackup_slave_infoCHANGE MASTER TO MASTER_LOG_FILE='mysql-bin-3306.000368', MASTER_LOG_POS=637921806;    #对应的binlog不一样

在prepare增量备份期间,可以看到一些信息:

①:undolog会被增量追加,如:

xtrabackup: page size for /data/dbbackup_dir/2//undo001.delta is 16384 bytesApplying /data/dbbackup_dir/2//undo001.delta to ./undo001...

②:共享表空间被增量追加,如:

xtrabackup: page size for /data/dbbackup_dir/2//ibdata1.delta is 16384 bytesApplying /data/dbbackup_dir/2//ibdata1.delta to ./ibdata1...

③:ibd文件被增量追加,如:

xtrabackup: page size for /data/dbbackup_dir/2//test/test.ibd.delta is 16384 bytesApplying /data/dbbackup_dir/2//test/test.ibd.delta to ./test/test.ibd...

④:frm、MYI、MYD被全量复制,如:

170822 14:04:51 [01] Copying /data/dbbackup_dir/2/test/test.frm to ./test/test.frm170822 14:04:51 [01]        ...done

⑤:没有看到TokuDB的增量和全量追加和复制,而且增量perpare完之后,全量备份里的tokudb文件被删除。

到这里增量备份已经prepare完成了,此时全量备份里的一些元数据文件已经被修改:

# cat full_backup/xtrabackup_checkpoints backup_type = full-preparedfrom_lsn = 0to_lsn = 371913526149    #已经把增量放进来了last_lsn = 371913526158compact = 0recover_binlog_info = 0# cat full_backup/xtrabackup_slave_infoCHANGE MASTER TO MASTER_LOG_FILE='mysql-bin-3306.000368', MASTER_LOG_POS=637921806; #更新成增量的信息

因为不支持TokuDB的增量,而且由于进行增量的prepare,导致全量备份里的tokudb文件被删除,所以需要手动进行复制TokuDB文件。从增量备份里复制tokudb相关的所有文件到全量备份,如:

/data/dbbackup_dir# mv 2/test/*tokudb full_backup/test/ /data/dbbackup_dir# mv 2/tokudb_log/* full_backup/tokudb_log//data/dbbackup_dir# mv 2/tokudb.directory full_backup//data/dbbackup_dir# mv 2/tokudb.environment full_backup//data/dbbackup_dir# mv 2/__tokudb_lock_dont_delete_me_data full_backup//data/dbbackup_dir# mv 2/tokudb.rollback full_backup/

要是不确定那些库有TokuDB引擎,可以通过下面的命令来查看和复制,来替换mv xxx/*.tokudb

#在增量备份里执行/data/dbbackup_dir/2#for i in `find . -iname "*\.tokudb"`; do echo "mv $i ../full_backup/"$dirname $i; done | awk -F "/ ./" '{print $1"/"$2}'

最后再次prepare全量备份,生成redo log:

/usr/local/xtrabackup_dir/bin/xtrabackup  --prepare  --use-memory=1G --target-dir=/data/dbbackup_dir/full_backup

到此已经生成了还原所需要的所有文件,只需要把这些文件放到数据目录即可。

3)还原,复制文件

注意:备份和还原的MySQL配置文件所配置的目录需要保持一致,如:undolog是否独立,tokudb必须不能指定目录,保证备份和还原MySQL目录的一致性。如果起来当一个从来服务则需要修改server_id。

1:复制文件到数据目录/data/dbbackup_dir# mv full_backup/* /var/lib/mysql/2:根据配置文件设置目录/var/lib/mysql# mkdir undolog/var/lib/mysql# mv undo00* undolog/3:修改权限/var/lib# chown -R mysql.mysql mysql/4:确定好目录没问题之后,就可以直接开启MySQL

如果MySQL已经正常启动,只需要执行start slave,不需要change就可以直接成为一个从服务。如果担心主从数据的一致性问题,可以通过来保证。后续如果遇到什么“坑”,会持续更新。

补充

如何处理一张表的还原呢?因为XtraBackup是整个实例还原的,所以对于还原恢复单个表的操作可以这样操作(必须开启innodb_file_per_table),用下面的方法替换原有的prepare方法,只需要执行一次即可

xtrabackup --prepare --export --target-dir=/data/dbbackup_dir/full_backup

export方法,执行完后,数据库目录下的表文件格式会试这样:

test.cfg  #包含了Innodb字典dumptest.exptest.frmtest.ibd

单表恢复还原:

1:先在MySQL里discard该表空间mysql> alter table test discard tablespace;2:在备份目录里把需要的表文件复制到数据库目录下上述的cfg、ibd、frm、exp的表文件复制过去cp ...  ...3:最后在MySQL里import该表空间mysql> alter table test import tablespace;4:验证

总结

到此,关于XtraBackup的全量、增量备份还原已经介绍完,总的来说:想要进行物理备份并且有TokuDB引擎,官方的版本不支持,需要使用BohuTANG改版过的XtraBackup,兼容官方版本。并且主要注意下面的情况:

1:不能设置tokudb_data_dir;2:不能自动的增量备份TokuDB,需要手动的复制Tokudb文件。3:备份和还原的MySQL大版本保持一致,而且设置目录的参数也要一样。4:尽量不要使用MyISAM,用InnoDB替换MyISAM,减少锁表时间。 5:加密的keyfile必须要和解密的keyfile一致。

备份相关命令总结:

1:普通全量备份 xtrabackup --defaults-extra-file=/etc/mysql/uupp.cnf --datadir=/var/lib/mysql --host=172.16.109.132 --log-copy-interval=10 --no-timestamp --slave-info --safe-slave-backup --backup --parallel=5  --target-dir=/data/33062:压缩全量备份:qpressxtrabackup --defaults-extra-file=/etc/mysql/uupp.cnf --datadir=/var/lib/mysql --host=172.16.109.132 --log-copy-interval=10 --no-timestamp --slave-info --safe-slave-backup --backup --parallel=5 --compress --compress-threads=3 --target-dir=/data/33063:压缩加密全量备份xtrabackup --defaults-extra-file=/etc/mysql/uupp.cnf --datadir=/var/lib/mysql --host=172.16.109.132 --log-copy-interval=10 --no-timestamp --slave-info --safe-slave-backup --backup --parallel=5 --compress --compress-threads=3 --encrypt=AES256 --encrypt-key-file=/data/keyfile --encrypt-threads=3  --target-dir=/data/33064:打包压缩加密全量备份:xtrabackup --defaults-extra-file=/etc/mysql/uupp.cnf --datadir=/var/lib/mysql --host=172.16.109.132 --log-copy-interval=10 --no-timestamp --slave-info --safe-slave-backup --backup --parallel=5 --compress --compress-threads=3 --stream=xbstream --encrypt=AES256 --encrypt-key-file=/data/keyfile --encrypt-threads=3  --target-dir=/data/3306/ > /data/3306/all_db.xbstream5:打包压缩加密传输到远程服务器,并在远程服务器解包xtrabackup --defaults-extra-file=/etc/mysql/uupp.cnf --datadir=/var/lib/mysql --host=172.16.109.132 --log-copy-interval=10 --no-timestamp --slave-info --safe-slave-backup --backup --parallel=5 --compress --compress-threads=3 --stream=xbstream --encrypt=AES256 --encrypt-key-file=/data/keyfile --encrypt-threads=3  --target-dir=/data/3306/ | ssh 172.16.109.133 "xbstream -x -C /data/"#解包xbstream -x < all_db.xbstream #解密for i in `find . -iname "*\.xbcrypt"`; do /usr/local/xtrabackup_dir/bin/xbcrypt -d --encrypt-key-file=/data/keyfile --encrypt-algo=AES256 < $i > $(dirname $i)/$(basename $i .xbcrypt) && rm $i; done#解压for f in `find ./ -iname "*\.qp"`; do qpress -dT2 $f  $(dirname $f) && rm -f $f; done #applyxtrabackup --prepare --apply-log-only --use-memory=1G --target-dir=/data/3306
View Code 

参考文档

 

转载地址:http://bjwxx.baihongyu.com/

你可能感兴趣的文章
c# byte char string转换
查看>>
图的实现(邻接链表C#)
查看>>
一个页面上有大量的图片(大型电商网站),加载很慢,你有哪些方法优化这些图片的加载,给用户更好的体验。...
查看>>
asyncio之Coroutines,Tasks and Future
查看>>
JS-完美运动框架(封装)
查看>>
美容院会籍管理,看着简单,其实很复杂
查看>>
Two Sum(leetcode1)
查看>>
浪潮各机型管理芯片BMC IP(智能平台管理接口)设置
查看>>
JSP是不是Java发展史上的一大败笔?
查看>>
【CF671D】 Roads in Yusland(对偶问题,左偏树)
查看>>
反编译sencha toucha打包的apk文件,修改应用名称支持中文以及去除应用标题栏
查看>>
Win32 API
查看>>
虚函数(1)
查看>>
动态使用webservice,以及含有ref类型的参数的问题
查看>>
微信小程序之可滚动视图容器组件 scroll-view
查看>>
项目中常用的 19 条 MySQL 优化总结
查看>>
Repeater 嵌套 绑定数据,嵌套的Repeater无法绑定的问题
查看>>
SRM598 Div1
查看>>
众数问题
查看>>
【第44题】【062题库】2019年OCP认证062考试新题
查看>>