数据库恢复方案

数据库恢复方案

摘要

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

目录

  • 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 条评论
登录 后参与评论

相关文章

来自专栏挖掘大数据

PipeLineDB数据库介绍和总结

PipelineDB 是开源的关系型数据库,可以在 streams 中持续运行 SQL 查询,逐渐将结果存储在表中。本文将对PipelineDB做相应的总结。

41800
来自专栏Netkiller

数据库恢复方案

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

31980
来自专栏MongoDB中文社区

深入解析MongoDB Plan Cache

前段时间笔者遇到一个MongoBD Plan Cache的bug,于是深究了下MongoDB优化器相关源码。在这里分享给大家,一方面让大家知道MongoDB优化...

12820
来自专栏PHP在线

比较全面的MySQL优化参考

本文整理了一些MySQL的通用优化方法,做个简单的总结分享,旨在帮助那些没有专职MySQL DBA的企业做好基本的优化工作,至于具体的SQL优化,大部分通过加适...

34440
来自专栏GreenLeaves

select for update和select for update wait和select for update nowait的区别

CREATE TABLE "TEST6" ( "ID" VARCHAR2(30), "NAME" VARCHAR2(30), "...

230100
来自专栏jouypub

Hive日常操作

根据分区查询数据:select table_coulm from table_name where partition_name = '2018-11-01';

26330
来自专栏架构师之路

数据库中间件cobar调研笔记

13年底负责数据库中间件设计时的调研笔记,拿出来和大家分享,轻拍。文章很长,可提前收藏,转发。 一,cobar是什么 开源的mysql的中间件服务 使用mysq...

44460
来自专栏Java架构师历程

MYSQL 浅谈MyISAM 存储引擎

       mysql中用的最多存储引擎就是innodb和myisam。做为Mysql的默认存储引擎,myisam值得我们学习一下,以下是我对《高性能MYSQ...

95920
来自专栏JMCui

SQL优化二(SQL性能调优)

一·、前言:这篇博文内容非原创,是我们公司的架构师给我们做技术培训的时候讲的内容,我稍微整理了下,借花献佛。这篇博文只是做一个大概的科普介绍,毕竟SQL优化的知...

43160
来自专栏任浩强的运维生涯

mongodb 性能篇

一、  索引及其优化 索引的概述 数据库的索引好比是一本书前面的目录,能加快数据查询的速度。 适当的地方增加索引,不合理的地方删除次优索引,能优化性能较差的应用...

473100

扫码关注云+社区

领取腾讯云代金券