数据库恢复方案

数据库恢复方案

摘要

这里所谈的内容是对备份数据的恢复,不是对损坏数据表的恢复,或者说灾难恢复。

目录

  • 1. 背景
  • 2. 备份方式分析
  • 3. 恢复方案
    • 3.1. 第一种
    • 3.2. 第二种
    • 3.3. 第三种
    • 3.4. 第四种
  • 4. 手工恢复

1. 背景

我们来假设一个场景。

你是否适用 mysqldump 每隔一段时间备份一次数据库,每个备份一个数据文件。

公司决策你是不是因为数据持续增加,有些数据已经不会再查询,会删除旧的历史数据。

有时公司突然说要恢复历史数据,有可能全补回复,有可能部分恢复。

你将怎么做?

2. 备份方式分析

首先看看备份方式,你是不是采用这种方法备份

我使用一串数字表述数据库数据递增情况,数据的增长变化

垂直轴表示备份时间轴

最常见的备份方法,完全备份

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...
|.......| 第一次备份
|.................| 第二次备份
|...........................| 第三次备份
|......................................| 第四次备份
|................................................| 第五次备份		

下面这种备份方式也比较常见,这种方式很有规律。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...
|.......| 第一次备份
        |..........| 删除上一次以备份内容,第二次备份
                   |..........| 删除上一次以备份内容,第三次备份数据库
                              |..........| 删除上一次以备份内容,第四次备份
                                         |.........| 删除上一次以备份内容,第五次备份		

更复杂的情况,无规律可循

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...
|.......| 第一次备份
|..................| 第二次备份
        |......................| 删除一部分数据后同时做第三次备份数据库
                   |......................| 又删除一部分数据,第四次备份
                   |.............................| 第五次备份,没有删除数据
                   |......................................| 第六次备份,依然没有删除数据
                                          |..........................| 删除很多数据,第七次备份		

以此类推,删除原因有多种,如空间不足,改善查询性能...等等

最杂的情况,无规律可循,同时交叉数据可能会有更新

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...
|...o...| 第一次备份
|.....o............| 第二次备份
        |....o...o.............| 删除一部分数据后同时做第三次备份数据库
                   |.o..o..o..............| 又删除一部分数据,第四次备份
                   |....o......o.......o.........| 第五次备份,没有删除数据
                   |.......o.......o.........o............| 第六次备份,依然没有删除数据
                                          |.o....o......o............| 删除很多数据,第七次备份		

我用'o' 表示与上次备份中有差异的部分。

3. 恢复方案

,最好恢复,第二种。

上面所提三种备份方式

  • 第一种
  • 最好恢复,100% 都能搞定.
  • 第二种
  • 恢复起来稍复杂,仍能搞得定.
  • 第三种
  • 比较复杂,因为本档案中存在重复记录,费点脑筋
  • 第四种
  • 最复杂,看似复杂,其实也不复杂,跟第三种差不多.

3.1. 第一种

这种备份非常简单,菜鸟也搞搞定

文本格式回复

cat dbname.sql | mysql -u user -p pass -h localhost yourdb			

压缩格式恢复

zcat dbname.sql.gz | mysql -u user -p pass -h localhost yourdb			

或者先使用gunzip解压,再恢复数据

gunzip dbname.sql.gz
cat dbname.sql | mysql -u user -p pass -h localhost yourdb			

提示

很多人喜欢用tar打包,我不见这样做,一个文件时无需使用tar打包的,画蛇添足

仅使用gzip压缩,可以方便使用zcat直接操作文件。

3.2. 第二种

这种备份是连续有规律的,只要依次按顺序恢复即可。

zcat dbname1.sql.gz | mysql -u user -p pass -h localhost yourdb
zcat dbname2.sql.gz | mysql -u user -p pass -h localhost yourdb
zcat dbname3.sql.gz | mysql -u user -p pass -h localhost yourdb
...
...
zcat dbname10.sql.gz | mysql -u user -p pass -h localhost yourdb			

也可以跳跃恢复数据

zcat dbname2.sql.gz | mysql -u user -p pass -h localhost yourdb
zcat dbname3.sql.gz | mysql -u user -p pass -h localhost yourdb
zcat dbname5.sql.gz | mysql -u user -p pass -h localhost yourdb
zcat dbname10.sql.gz | mysql -u user -p pass -h localhost yourdb			

反向恢复数据

zcat dbname20.sql.gz | mysql -u user -p pass -h localhost yourdb
zcat dbname15.sql.gz | mysql -u user -p pass -h localhost yourdb
zcat dbname13.sql.gz | mysql -u user -p pass -h localhost yourdb
zcat dbname1.sql.gz | mysql -u user -p pass -h localhost yourdb			

总之怎么恢复都可以

3.3. 第三种

这种恢复建议按照顺序进行,因为重叠数据没有变化,所以即可以顺时间轴恢复也可以逆时间轴,条件是表结构需要有主键(PK)

insert 方式有要求

必须是

INSERT INTO dbtable(f1, f2, f3...) value (v1, v2, v3);
INSERT INTO dbtable(f1, f2, f3...) value (v1, v2, v3);
INSERT INTO dbtable(f1, f2, f3...) value (v1, v2, v3);				

不能是

INSERT INTO dbtable(f1, f2, f3...) value (v1, v2, v3), (v1, v2, v3), value (v1, v2, v3);				

这种备份参数如下

mysqldump -C -hlocalhost -ubackup -p1AyBoc5mp02LDJki5wJ8 --skip-extended-insert -t db_name tbl_name				

这种方式备份,备份文件尺寸会比较大。

正时序恢复案例,

zcat dbname1.sql.gz | sed 's/^INSERT INTO/INSERT IGNORE INTO/' | mysql -u user -p pass -h localhost yourdb
zcat dbname2.sql.gz | sed 's/^INSERT INTO/INSERT IGNORE INTO/' | mysql -u user -p pass -h localhost yourdb
zcat dbname3.sql.gz | sed 's/^INSERT INTO/INSERT IGNORE INTO/' | mysql -u user -p pass -h localhost yourdb			

逆时序恢复数据

zcat dbname3.sql.gz | sed 's/^INSERT INTO/INSERT IGNORE INTO/' | mysql -u user -p pass -h localhost yourdb
zcat dbname2.sql.gz | sed 's/^INSERT INTO/INSERT IGNORE INTO/' | mysql -u user -p pass -h localhost yourdb
zcat dbname1.sql.gz | sed 's/^INSERT INTO/INSERT IGNORE INTO/' | mysql -u user -p pass -h localhost yourdb			

因为有主键,所以已存在的重复记录不会被重复插入。

3.4. 第四种

这种恢复必须按照顺序进行,即可以顺时间轴恢复也可以逆时间轴,但处理上稍有不同.一旦操作错误数据就会损坏,同时也有很多条件。

顺时序恢复数据, 只需将 insert 替换为 replace 即可

replace into dbtable(f1, f2, f3...) value (v1, v2, v3);
replace into dbtable(f1, f2, f3...) value (v1, v2, v3);
replace into dbtable(f1, f2, f3...) value (v1, v2, v3);			

新数据总会覆盖旧数据

但逆向就不同了,逆时序恢复数据与上面第三种相同, 恢复过程中旧数据在 insert 的时候不会覆盖现有的新数据。仅仅将失去的数据恢复到数据库中。

操作要十分谨慎,理解正向与逆向的不同,方能操作。

4. 手工恢复

有时上面所讲的四种恢复方法不能满足你需求,我们模拟一个场景,假如你需要恢复一个时间段的数据,或者ID字段去一个范围等等,上面所举例子均为一刀切。该怎么办呢?

不用担心方法总是有的

INSERT ... SELECT

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    SELECT ...
    [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]		

REPLACE ... SELECT

REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name
    [PARTITION (partition_name,...)]  
    [(col_name,...)]
    SELECT ...		

例 1. INSERT ... SELECT

INSERT IGNORE INTO tbl_name_new SELECT * FROM tbl_name_old WHERE name = 'netkiller';
INSERT IGNORE INTO db_new.tbl_name SELECT * FROM db_old.tbl_name WHERE id > '10000';			

IGNORE 将忽略 ERROR 1062 (23000) at line 24: Duplicate entry '100' for key 'PRIMARY'

这里仅给一个简单实例,因为每个人的需求都不同,你只需灵活变通,发挥你的想象力。

原文发布于微信公众号 - Netkiller(netkiller-ebook)

原文发表时间:2017-04-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏乐沙弥的世界

MySQL视图

视图是关系型数据库重要的组成部分之一,它可以限制数据访问,简化复杂查询,保持数据的独立性,以及基于相同的数据提供不同的视图等等。本文介绍MySQL数据库视图的一...

672
来自专栏idba

死锁案例之五

死锁其实是一个很有意思也很有挑战的技术问题,大概每个DBA和部分开发朋友都会在工作过程中遇见。关于死锁我会持续写一个系列的案例分析,希望能够对想了解死锁的朋友...

784
来自专栏芋道源码1024

事务隔离级别和脏读的快速入门

仅从ACID或非ACID角度考虑问题是不够的,你应知道你的数据库支持何种事务隔离级别。

501
来自专栏技术博文

从MyISAM转到InnoDB需要注意什么

转自 MySql中文网 http://mp.weixin.qq.com/s?__biz=MjM5NzAzMTY4NQ==&mid=200910426&idx=1...

33814
来自专栏帘卷西风的专栏

关于mysql存储过程创建动态表名及参数处理

转载请注明出处:帘卷西风的专栏(http://blog.csdn.net/ljxfblog) 

603
来自专栏李蔚蓬的专栏

RFID课程前置——SQL巩固练习

-- 5) 输出所有数据的拨号流水,并且在最后一行添加总呼叫时长。 -- 记录呼叫员编号、对方号码、通话时长 --... -- 汇总[市内号码总时长][长...

744
来自专栏Laoqi's Linux运维专列

Mysql中MyISAM引擎和InnoDB引擎的比较

结论 如果不清楚自己应该用什么引擎,那么请选择InnoDB,Mysql5.5+的版本默认引擎都是InnoDB,早期的Mysql版本默认的引擎是MyISAM --...

3396
来自专栏用户2442861的专栏

MySQL性能优化的最佳20+条经验

今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显。关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的...

502
来自专栏程序猿

MySQL优化方案(一)优化SQL脚本与索引

MySQL的优化方案有哪一些? 本文记录MySQL优化方案 ,梗概如下: 优化SQL 优化索引 (一)优化SQL 1、通过MySQL自有的优化语句 优化SQL语...

3937
来自专栏Linyb极客之路

MySQL 表锁和行锁机制

行锁变表锁,是福还是坑?如果你不清楚MySQL加锁的原理,你会被它整的很惨!不知坑在何方?没事,我来给你们标记几个坑。遇到了可别乱踩。通过本章内容,带你学习My...

1113

扫码关注云+社区