MySQL数据库备份与恢复
1、备份方式
- 逻辑备份(文本表示:SQL 语句)
- 物理备份(数据文件的二进制副本)
- 基于快照的备份
- 基于复制的备份
- 增量备份(刷新二进制日志)
2、备份类型
2.1 热备份
这些动态备份在读取或修改数据的过程中进行,很少中断或者不中断传输或处理数据的功能。使用热备份时,系统仍可供读取和修改数据的操作访问。
2.2冷备份
这些备份在用户不能访问数据时进行,因此无法读取或修改数据。这些脱机备份会阻止执行任何使用数据的活动。这些类型的备份不会干扰正常运行的系统的性能。但是,对于某些应用程序,会无法接受必须在一段较长的时间里锁定或完全阻止用户访问数据。
2.3温备份
这些备份在读取数据时进行,但在多数情况下,在进行备份时不能修改数据本身。这种中途备份类型的优点是不必完全锁定最终用户。但是,其不足之处在于无法在进行备份时修改数据集,这可能使这种类型的备份不适用于某些应用程序。在备份过程中无法修改数据可能产生性能问题。
3、物理备份
物理备份由存储数据库内容的目录和文件的原始副本组成。这种类型的备份适用于需要在发生问题时快速恢复的大型重要数据库。
3.1物理备份的特点
- 备份由数据库目录和文件的精确副本组成。通常这是全部或部分MySQL数据目录的副本。
- 物理备份方法比逻辑更快,因为它们只涉及文件复制而无需转换。
- 输出比逻辑备份更紧凑。
- 由于备份速度和紧凑性对繁忙,重要的数据库非常重要,MySQL企业备份产品可以执行物理备份。份的特点:
- 备份和恢复从整个数据目录级别到单个文件级别的粒度范围。这可能会也可能不会提供表级粒度,具体取决于存储引擎。例如, InnoDB表可以分别放在一个单独的文件中,或与其他InnoDB表共享文件存储 ; 每个 MyISAM表格唯一对应一组文件。
- 除数据库外,备份还可以包含任何相关文件,如日志或配置文件。
- 来自MEMORY表的数据很难以这种方式备份,因为它们的内容不存储在磁盘上。(MySQL企业备份产品具有可以MEMORY在备份过程中从表中检索数据的功能。)
- 备份只能移植到具有相同或相似硬件特性的其他机器。
- 备份可以在MySQL服务器不运行时执行。如果服务器正在运行,则需要执行适当的锁定,以便服务器在备份期间不更改数据库内容。MySQL Enterprise Backup会自动为需要它的表执行此锁定。
- 物理备份工具包括 mysqlbackup MySQL企业备份的 InnoDB或任何其他桌,文件系统级的命令(如CP, SCP,焦油, rsync的),或mysqlhotcopy的 对MyISAM表。
- 为了恢复:
- MySQL企业备份还原InnoDB 和其他备份的表。
- ndb_restore恢复 NDB表格。
- 可以使用文件系统命令 将文件系统级别或使用mysqlhotcopy复制的文件 复制回原来的位置。
4、逻辑备份
逻辑备份保存表示为逻辑数据库结构(CREATE DATABASE, CREATE TABLE语句)和内容(INSERT语句或分隔文本文件)的信息。这种类型的备份适用于可能编辑数据值或表结构的较小数据量,或者在不同的计算机体系结构上重新创建数据。
4.1逻辑备份的特点
- 备份是通过查询MySQL服务器来获得数据库结构和内容信息。
- 备份比物理方法慢,因为服务器必须访问数据库信息并将其转换为逻辑格式。如果输出写入客户端,服务器也必须将其发送到备份程序。
- 输出大于物理备份,特别是以文本格式保存时。
- 在服务器级别(所有数据库),数据库级别(特定数据库中的所有表)或表级别都可以使用备份和还原粒度。无论存储引擎如何,情况都是如此。
- 备份不包括日志或配置文件,或其他不属于数据库的与数据库相关的文件。
- 以逻辑格式存储的备份与机器无关并且非常便携。
- 逻辑备份是在MySQL服务器运行的情况下执行的。服务器没有脱机。
- 逻辑备份工具包括mysqldump 程序和SELECT … INTO OUTFILE语句。这些适用于任何存储引擎,甚至MEMORY。
- 要恢复逻辑备份,可以使用mysql客户端处理SQL格式的转储文件。要加载分隔文本文件,请使用 LOAD DATA INFILE语句或 mysqlimport客户端。
5、备份工具
1.mysqldump
- mysql原生自带很好用的逻辑备份工具
2.mysqlbinlog
- 实现binlog备份的原生态命令
3.xtrabackup
- precona公司开发的性能很高的物理备份工具
5.1mysqldump介绍
5.1.1语法
Usage: mysqldump [OPTIONS] database [tables] OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...] OR mysqldump [OPTIONS] --all-databases [OPTIONS]
5.1.2参数
-A, --all-databases Dump all the databases. #全库 -B, --databases Dump several databases. #单库 -d #仅表结构 -t #仅数据 --compact #减少无用数据输出(调试) -R, --routines #备份存储过程和函数数据 --triggers #备份触发器数据 --master-data={1|2} #告诉你备份后时刻的binlog位置,2:注释;1:非注释,要执行(主从复制) --master-data #自动进行锁表和释放锁 --single-transaction #对innodb引擎进行热备 -x #锁住所有备份表 -l #锁住单表 -F, --flush-logs #刷新binlog日志(回顾binlog)
5.2使用
5.2.1 全库备份
[root@db02 ~]# mkdir /backup [root@db02 ~]# mysqldump -A >/backup/full.sql #注意:mysqldump恢复数据必须数据库是开启状态下,假如数据库数据目录被删除,那么此时就需要重新初始化数据库,然后启动数据库,更新密码,然后登陆数据库,进行source 命令进行恢复
5.2.2 备份多个表
mysqldump库1 表1 表2 表3 >库1.sql mysqldump库2 表1 表2 表3 >库2.sql #单表备份: mysqldump -uroot -p123 oldboy test>/backup/test.sql
5.2.3 分库备份:for循环
mysqldump-uroot-p\'oldboy123\' -B oldboy... mysqldump-uroot-p\'oldboy123\' -B oldboy_utf8 ... mysqldump-uroot-p\'oldboy123\' -B mysql... for 循环: for name in `mysql-e "show databases;"|sed1d` do mysqldump-uroot-p\'oldboy123\' -B $name done
- 例子:每天晚上0点备份数据库
mysqldump-A -B -F >/opt/$(date +%F).sql [root@db02 ~]# ll/application/mysql/logs/ -rw-rw----1 mysqlmysql168 Jun 21 12:06 oldboy-bin.000001 -rw-rw----1 mysqlmysql168 Jun 21 12:06 oldboy-bin.000002 -rw-rw----1 mysqlmysql210 Jun 21 12:07 oldboy-bin.index #提示:每个库都会刷新一次
5.2.4 指定备份的位置
[root@db02 logs]# sed-n \'22p\' /opt/t.sql --CHANGE MASTER TO MASTER_LOG_FILE=\'oldboy-bin.000005\', MASTER_LOG_POS=344; [root@db02 logs]# mysqldump-B --master-data=2 oldboy>/opt/t.sql
5.2.5 锁表备份
- 锁表:适合所有引擎(myisam,innodb)
-x, --lock-all-tables -l, --lock-tables mysqldump-B -x oldboy>/opt/t.sql
- 基于事务引擎:不用锁表就可以获得一致性的备份.
- 生产中99% 使用innodb事务引擎.
- ACID四大特性中的隔离性
5.2.6 压缩备份:
mysqldump-B --master-data=2 oldboy|gzip>/opt/t.sql.gz 解压: zcatt.sql.gz>t1.sql gzip-d t.sql.gz#删压缩包
5.2.7 innodb引擎的备份命令如下:
mysqldump-A -B -R --triggers --master-data=2 --single-transaction |gzip>/opt/all.sql.gz 适合多引擎混合(例如:myisam与innodb混合)的备份命令如下: mysqldump-A -B -R --triggers --
5.2.8 扩展
- 例子1:全库中全表的备份语句拼接
select concat("mysqldump"," -uroot -p123 " ,table_schema," ",table_name, " ",">/backup/",table_name,".sql") from information_schema.tables;
- 例子2:所有数据库备份的语句拼接
select concat("mysqldump"," -uroot -p123 -B " ,table_schema," ", " ",">/backup/",table_schema,".sql") from information_schema.tables group b y(table_schema);
6、使用Mysqldump备份进行恢复实践
- 备份innodb引擎数据库oldboy并压缩:
mysqldump-B -R --triggers --master-data=2 oldboy|gzip>/opt/alL_$(date +%F).sql.gz
- 人为删除oldboy数据库:
[root@db02 opt]# mysql-e “drop database oldboy;” [root@db02 opt]# mysql-e “show databases;”
- 恢复数据库:
使用gzip解压 gzip-d xxx.gz 数据库命令行 source /opt/alL_2017-06-22.sql
- 验证数据:
[root@db02 opt]# mysql-e “use oldboy;select* from test;”
7、Mysqldump+Mysqlbinlog企业级增量备份恢复实战
背景环境:
正在运行的网站系统,mysql数据库,数据量25G,日业务增量10-15M。
备份方式:
每天23:00点,计划任务调用mysqldump执行全备脚本
故障时间点:
上午10点,误删除了一个表
如何恢复?
思路
1.使用测试库,恢复全备 使用source
2.恢复此表从23:00到10点之间的binlog
2.1截取23:00到10点这段binlog在测试库恢复
2.2导出删除表
3.将删除的表进行恢复 到生产库
注意
在生产库环境中,出现这种误操作,数据损坏,那么尽量避免对数据库进行进一步“伤害“了,iptables 3306端口关闭掉 ,skip-network mysql自带的放置网络连接的方法,但是需要加入配置文件重启实例,等到恢复完成,再放开连接。
8、mysqldump企业级备份策略设计与实践
- 全量备份概念
全量数据就是数据库中所有的数据(或某一个库的全部数据); 全量备份就是把数据库中所有的数据进行备份。 mysqldump会取得一个时刻的一致性数据.
- 增量备份
增量数据就是指上一次全量备份数据之后到下一次全备之前数据库所更新的数据 对于mysqldump,binlog就是增量数据.
- 设计备份策略
设计备份脚本和计划任务 定期的恢复演练
9、MySQL物理备份工具xtrabackup
9.1安装
wget-O /etc/yum.repos.d/epel.repohttp://mirrors.aliyun.com/repo/epel-6.repo yum -y install perlperl-devellibaiolibaio-develperl-Time-HiResperl-DBD-MySQL wgethttps://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.4/binary/redhat/6/x86_64/percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm yum -y install percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm
9.2备份命令
xtrabackup innobackupex******
10、MySQL物理备份工具xtrabackup案例实战
1、全备备份
mkdir -p /backup [root@db02 full]# innobackupex --user=root --password=123456 --socket=/tmp/mysql.sock --no-timestamp /backup/full1 #备份命令 innobackupex --user=root --password=123456 --use-memory=32M --no-timestamp /backup/xfull/
2、恢复数据前的准备(合并xtabackup_log_file和备份的物理文件)
innobackupex--apply-log --use-memory=32M /backup/xfull/
3、停库
ill -9 pid lsof -i:3306
4、破坏数据
cd/application/mysql/ mv data /opt/
5、恢复
#第一种 cp -a /backup/xfull/* /application/mysql/data/ chown -R mysql.mysql /application/mysql/data/ #第二种 innobackupex --copy-back /backup/xfull/ chown -R mysql.mysql /application/mysql/data/
6、启动
/etc/init.d/mysqld start mysql -e "select * from oldboy.test" 注:我们还可以使用—copy-back参数进行恢复
11、Xtrabackup备份
11.1 介绍
1、特点
物理备份工具,在同级数据量基础上,都要比逻辑备份性能高特别是在数据量比较大的时候,体现的更价明显
2、备份方式
- 拷贝数据文件
- 拷贝数据页
3、xtrabackup 参数说明(xtrabackup –help )
--apply-log-only:prepare备份的时候只执行redo阶段,用于增量备份。 --backup:创建备份并且放入--target-dir目录中 --close-files:不保持文件打开状态,xtrabackup打开表空间的时候通常不会关闭文件句柄,目的是为了正确处理DDL操作。如果表空间数量非常巨大并且不适合任何限制,一旦文件不在被访问的时候这个选项可以关闭文件句柄.打开这个选项会产生不一致的备份。 --compact:创建一份没有辅助索引的紧凑备份 --compress:压缩所有输出数据,包括事务日志文件和元数据文件,通过指定的压缩算法,目前唯一支持的算法是quicklz.结果文件是qpress归档格式,每个xtrabackup创建的*.qp文件都可以通过qpress程序提取或者解压缩 --compress-chunk-size=#:压缩线程工作buffer的字节大小,默认是64K --compress-threads=#:xtrabackup进行并行数据压缩时的worker线程的数量,该选项默认值是1,并行压缩(\'compress-threads\')可以和并行文件拷贝(\'parallel\')一起使用。例如:\'--parallel=4 --compress --compress-threads=2\'会创建4个IO线程读取数据并通过管道传送给2个压缩线程。 --create-ib-logfile:这个选项目前还没有实现,目前创建Innodb事务日志,你还是需要prepare两次。 --datadir=DIRECTORY:backup的源目录,mysql实例的数据目录。从my.cnf中读取,或者命令行指定。 --defaults-extra-file=[MY.CNF]:在global files文件之后读取,必须在命令行的第一选项位置指定。 --defaults-file=[MY.CNF]:唯一从给定文件读取默认选项,必须是个真实文件,必须在命令行第一个选项位置指定。 --defaults-group=GROUP-NAME:从配置文件读取的组,innobakcupex多个实例部署时使用。 --export:为导出的表创建必要的文件 --extra-lsndir=DIRECTORY:(for --bakcup):在指定目录创建一份xtrabakcup_checkpoints文件的额外的备份。 --incremental-basedir=DIRECTORY:创建一份增量备份时,这个目录是增量别分的一份包含了full bakcup的Base数据集。 --incremental-dir=DIRECTORY:prepare增量备份的时候,增量备份在DIRECTORY结合full backup创建出一份新的full backup。 --incremental-force-scan:创建一份增量备份时,强制扫描所有增在备份中的数据页即使完全改变的page bitmap数据可用。 --incremetal-lsn=LSN:创建增量备份的时候指定lsn。 --innodb-log-arch-dir:指定包含归档日志的目录。只能和xtrabackup --prepare选项一起使用。 --innodb-miscellaneous:从My.cnf文件读取的一组Innodb选项。以便xtrabackup以同样的配置启动内置的Innodb。通常不需要显示指定。 --log-copy-interval=#:这个选项指定了log拷贝线程check的时间间隔(默认1秒)。 --log-stream:xtrabakcup不拷贝数据文件,将事务日志内容重定向到标准输出直到--suspend-at-end文件被删除。这个选项自动开启--suspend-at-end。 --no-defaults:不从任何选项文件中读取任何默认选项,必须在命令行第一个选项。 --databases=#:指定了需要备份的数据库和表。 --database-file=#:指定包含数据库和表的文件格式为databasename1.tablename1为一个元素,一个元素一行。 --parallel=#:指定备份时拷贝多个数据文件并发的进程数,默认值为1。 --prepare:xtrabackup在一份通过--backup生成的备份执行还原操作,以便准备使用。 --print-default:打印程序参数列表并退出,必须放在命令行首位。 --print-param:使xtrabackup打印参数用来将数据文件拷贝到datadir并还原它们。 --rebuild_indexes:在apply事务日志之后重建innodb辅助索引,只有和--prepare一起才生效。 --rebuild_threads=#:在紧凑备份重建辅助索引的线程数,只有和--prepare和rebuild-index一起才生效。 --stats:xtrabakcup扫描指定数据文件并打印出索引统计。 --stream=name:将所有备份文件以指定格式流向标准输出,目前支持的格式有xbstream和tar。 --suspend-at-end:使xtrabackup在--target-dir目录中生成xtrabakcup_suspended文件。在拷贝数据文件之后xtrabackup不是退出而是继续拷贝日志文件并且等待知道xtrabakcup_suspended文件被删除。这项可以使xtrabackup和其他程序协同工作。 --tables=name:正则表达式匹配database.tablename。备份匹配的表。 --tables-file=name:指定文件,一个表名一行。 --target-dir=DIRECTORY:指定backup的目的地,如果目录不存在,xtrabakcup会创建。如果目录存在且为空则成功。不会覆盖已存在的文件。 --throttle=#:指定每秒操作读写对的数量。 --tmpdir=name:当使用--print-param指定的时候打印出正确的tmpdir参数。 --to-archived-lsn=LSN:指定prepare备份时apply事务日志的LSN,只能和xtarbackup --prepare选项一起用。 --user-memory = #:通过--prepare prepare备份时候分配多大内存,目的像innodb_buffer_pool_size。默认值100M如果你有足够大的内存。1-2G是推荐值,支持各种单位(1MB,1M,1GB,1G)。 --version:打印xtrabackup版本并退出。 --xbstream:支持同时压缩和流式化。需要客服传统归档tar,cpio和其他不允许动态streaming生成的文件的限制,例如动态压缩文件,xbstream超越其他传统流式/归档格式的的优点是,并发stream多个文件并且更紧凑的数据存储(所以可以和--parallel选项选项一起使用xbstream格式进行streaming)。
11.2 备份原理(innodb)
1、对于innodb表,可以实现热备
(1)在数据还有修改操作的时刻,直接将数据文件中的数据页备份,此时备份走的数据对于当前mysql来讲是不一致的
(2)将备份过程中的redo和undo一并备走
(3)为了恢复的时候,只要将保证备份出来的数据页LSN能和redo的LSN匹配,那么数据就是一致的。需要做redo和undo的应用。(查看有没有commit标记,有可以直接写入数据,没有可以回滚数据达成一致性)
2、对于myisam表,实现自动锁表拷贝文件。
可以直接锁表,然后就不能做任何修改了,实现了备份
3、增量备份
(1)起点问题
基于上一次备份进行增量
redo默认情况下是一组两个文件并且有固定大小。是一种轮询使用方式,不是永久的,有可能随时被覆盖。
(2)备份的是什么
1、可以使用binlog作为增量
2、自带增量备份,基于上次备份后变化的数据页,还要在备份过程中的redo和undo的变化
(3)怎么备份
#1、全备 innobackupex --user=root --password=123456 --use-memory=32M --no-timestamp /backup/xfull/ #2、对原库进行修改数据 #3、增量备份 innobackupex --user=root --password=123456 --incremental --no-timestamp --incremental-basedir=/backup/xfull/ /backup/xinc1/
(4)怎么恢复
#1、应用全备日志(--apply-log),暂时不需要做回滚操作(--redo-only) innobackupex --apply-log --redo-only /backup/xfull/ #2、增量合并到全备中(一致性的合并) innobackupex --apply-log --incremental-dir=/backup/xinc1/ /backup/xfull/ #3、合并完成恢复
(5)备份策略
周日进行全备 周一到周六 每天做上一天的增备 xfull --apply-log --redo-only 保证last-lsn=周一增量开始lsn xinc1 合并周一的增量到全备,并apply-log --redo-only 保证last-lsn=周二增量开始lsn xinc2 合并周二的增量到全备,并apply-log --redo-only 保证last-lsn=周三增量开始lsn xinc3 -- xinc4 --- xinc5 --- xinc6 合并周六的增量到全备,--apply-log 准备恢复即可
12、Xtrabackup企业级增量备份实战
背景:
某大型网站,mysql数据库,数据量500G,每日更新量100M-200M
备份策略:
xtrabackup,每周六1:00进行全备,周一到周五及周日1:00进行增量备份。
故障场景:
周三下午2点出现数据库意外删除表操作。
如何恢复?
思路:
1.断开所有应用?
2.检查备份是否存在
3.怎么快速、安全恢复
具体流程
1、准备上周六全备,并--apply-log --redo-only
2、合并增量,周日
案例模拟
#1、创建目录 [root@db02 backup]# mkdir -p /backup/full [root@db02 backup]# mkdir -p /backup/ inc1 inc2 #2、周日全备 [root@db02 ~]# innobackupex --user=root --password=123456 --no-timestamp /backup/full/ #3、模拟数据变化 mysql> use oldboy mysql> insert into test values(8,\'outman\',99); mysql> insert into test values(9,\'outgirl\',100); mysql> commit; #4、周一增量备份 [root@db02 ~]# innobackupex --user=root --password=123456 --incremental --no-timestamp --incremental-basedir=/backup/full/ /backup/inc1 #5、模拟周二数据变化 mysql> use oldboy mysql> insert into test values(10,\'outman1\',119); mysql> insert into test values(11,\'outgirl1\',120); mysql> commit; #6、周二增量备份 [root@db02 ~]# innobackupex --user=root --password=123456 --incremental --no-timestamp --incremental-basedir=/backup/inc1 /backup/inc2 #在插入新的行操作 mysql> use oldboy mysql> insert into test values(12,\'outman2\',19); mysql> insert into test values(13,\'outgirl2\',20); mysql> commit; #7、模拟场景:周二下午误删除test表 mysql> use oldboy; mysql> drop table test; #8、准备恢复 #8.1准备XtraBackup备份 innobackupex --apply-log --redo-only /backup/full/ innobackupex --apply-log --redo-only --incremental-dir=/backup/inc1 /backup/full/ innobackupex --apply-log --incremental-dir=/backup/inc2 /backup/full/ 最后应用全备 innobackupex --apply-log /backup/full/ #8.2确认binlog起点 [root@db02 ~]# cd /backup/inc2/ [root@db02 inc2]# cat xtrabackup_binlog_info mysql-bin.000001 960 [root@db02 inc2]# #8.2截取drop操作之前的binlog mysqlbinlog --start-position=960 /tmp/mysql-bin.000001 #找到drop之前的events和position号做截取 ,假如到1437,导出binlog mysqlbinlog mysql-bin.000001 --start-position=554 --stop-position=771 > /backup/binlog.sql #导入binlog set sql_log_bin=0; source /backup/binlog.sql #8.4 关闭数据库,备份二进制日志 /etc/init.d/mysqld stop cd /application/mysql/data/ cp mysql-bin.000001 /tmp/ #8.5 删除MySQL所有数据 cd /application/mysql/data/ rm -rf * #9、恢复数据 innobackupex --copy-back /backup/full chown -R mysql:mysql /application/mysql/data/ /etc/init.d/mysqld start
问题
恢复窗口要多长时间?——预计3个小时
数据很大,但是只是误删除了一张表,那么就只需要把这个表恢复了就可以了。
(1)“导出”表 导出表是在备份的prepare阶段进行的,因此,一旦完全备份完成,就可以在prepare过程中通过--export选项将某表导出了: # innobackupex --apply-log --export /path/to/backup 此命令会为每个innodb表的表空间创建一个以.exp结尾的文件,这些以.exp结尾的文件则可以用于导入至其它服务器。 (2)“导入”表 要在mysql服务器上导入来自于其它服务器的某innodb表,需要先在当前服务器上创建一个跟原表表结构一致的表,而后才能实现将表导入: mysql> CREATE TABLE mytable (...) ENGINE=InnoDB; 然后将此表的表空间删除: mysql> ALTER TABLE mydatabase.mytable DISCARD TABLESPACE; 接下来,将来自于“导出”表的服务器的mytable表的mytable.ibd和mytable.exp文件复制到当前服务器的数据目录,然后使用如下命令将其“导入”: mysql> ALTER TABLE mydatabase.mytable IMPORT TABLESPACE;