NoSQL-Mongodb备份恢复 (三)

8. 备份恢复

8.1 备份恢复工具

(1)**  mongoexport/mongoimport
(2)***** mongodump/mongorestore

8.2 备份工具区别

# 应用场景总结:
## (1) mongoexport/mongoimport(备份出来json或csv文件)
异构平台迁移 mysql <---> mongodb
同平台,跨大版本 mongodb 2 ----> mongodb 3

## (2) mongodump/mongorestore(dump/restore) BSON格式
日常备份恢复时使用

# 小提示:
mongodump可以理解为物理备份因为导出的是二进制的json
mongoexport逻辑备份导出来的json类的文本格式,只能按表导出,不能整个库导出来
mysql直接into outfile导出的表数据可以直接导入mongodb里面

8.3 导出工具mongoexport

# mongoexpot具体用法如下所示:
$ mongoexport --help  
参数说明:
-h:指明数据库宿主机的IP
-u:指明数据库的用户名
-p:指明数据库的密码
-d:指明数据库的名字
-c:指明collection的名字
-f:指明要导出那些列
-o:指明到要导出的文件名
-q:指明导出数据的过滤条件
--authenticationDatabase admin (这个是验证库,去mongondb一中查看什么是验证库)

# 1. 单表备份至json格式
mongoexport -uroot -p123456 --port 27017 --authenticationDatabase admin -d oldboy -c log  -o /mongodb/log.json
注:备份文件的名字可以自定义,默认导出了JSON格式的数据。

# 2. 单表备份至csv格式
如果我们需要导出CSV格式的数据,则需要使用--tpye=csv参数:
mongoexport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log --type=csv -f uid,name,age,date -o /mongodb/log.csv

开始实验:

# 1. 登录mongodb
[mongod@db01 ~]$ mongo -uroot -p123456 admin

# 2. 进入oldboy库,往log库(集合)中录入数据
> use oldboy
> for(i=1;i<10000;i++){db.log.insert({"uid":i,"name":"mongodb","age":6,"date":new Date()})}

# 3. 单表备份至json格式
[mongod@db01 ~]$ mongoexport -uroot -p123456 --port 27017 --authenticationDatabase admin -d oldboy -c log  -o /mongodb/log.json
[mongod@db01 ~]$ ll /mongodb/log.json 
-rw-rw-r-- 1 mongod mongod 1277648 8月  20 22:03 /mongodb/log.json

# 4. 单表备份至csv格式
[mongod@db01 ~]$ mongoexport -uroot -p123465 --port 27017 --authenticationDatabase admin -d oldboy -c log --type=csv -f uid,name,age,date -o /mongodb/log.csv
[mongod@db01 ~]$ ll /mongodb/log.csv 
-rw-rw-r-- 1 mongod mongod 158895 8月  20 22:07 /mongodb/log.csv

8.4 导入工具mongoimport

$ mongoimport --help
参数说明:
-h: 指名数据库宿主机的IP
-u: 指名数据库的用户名
-p: 指名数据库的密码
-d: 指名数据库的名字
-c: 指名collection的名字
-f: 指名要导入哪些列
-j,--numInsertionWorkers=<number> number of insert operations to run 
oncurrently
//并行

# 数据恢复:
# 1. 恢复json格式表数据到log1
mongoimport -uroot -p123456 --port 27017 --authenticationDatabase admin -d oldboy -c log1 /mongodb/log.json

# 2. 恢复csv格式的文件到log2
## (1) 标准mongodb csv格式导出文件
mongoimport -uroot -p123456 --port 27017 --authenticationDatabase admin -d oldboy -c log2 --type=csv  --headerline --file /mongodb/log.csv

--headerline:指名第一行是列名,不需要导入

## (2) 不标准的CSV,第一行不是列名
mongoimport -uroot -p123456 --port 27017 --authenticationDatabase admin -d oldboy -c log3 --type=csv -f id,name,age,date --file /mongodb/log.csv

8.5 异构平台迁移案例

异构平台迁移案例:MySQL 100w数据迁移MongoDB
mysql —> mongodb
test数据库下t100w表进行导出,导入到mongodb

# 1. mysql开启安全路径
vim /etc/my.cnf  --->添加一下配置
secure-file-priv=/tmp
--重启数据库生效
/etc/init.d/mysqld restart

# 2. 导出mysql的city表数据
select * form test.t100w into outfile 'tmp/2.csv' fields terminated by ',';


# 3. 导出列名, 把列名放到2.csv的第一行(可以使用文件合并方式导入)
> select group_concat(column_name) from information_schema.columns where table_schema='test' and table_name='t100w';

# 4. 在mongodb中导入备份
mongoimport -uroot -p123456 --port 27017 --authenticationDatabase admin -d test -c t100w --type=csv --headerline --file /tmp/2.csv

扩展: mongodb往mysql迁移(这种用的少)

mysql导出csv:
select * from test_info
into outfile '/tmp/test.csv'
fields terminated by ','    -----字段间以,号分割
optionally enclosed by '"'  -----字段用"号括起
escaped by '"'			    -----字段中使用的转义符为"
lines terminated by '\r\n'; -----行以\r\n结束

mysql导入csv:
load data infile '/tmp/test.csv'
into table test_info
fields terminated by '"'
escaped by '"'
lines terminated by '\r\n';

8.6 mongodump和mongorestore

8.6.1 mongodump介绍
mongodump能够在Mongodb运行时进行备份,他的工作原理是对运行的Mongodb做查询,
然后将所有查到的文档写入磁盘,到那时存在的问题是使用mongodump产生的备份不一定
是数据库的实时快照,如果我们在备份时对数据库进行了写入操作,则备份出来的文件可
能不完全和Mongodb实时数据相等。另外在备份时可能会对其他客户端性能产生不利的影响。
8.6.2 mongodump参数选项
mongodump用法
$ mongodump --help
参数说明:
-h:指明数据库宿主机的IP
-u:指明数据库的用户名
-p:指明数据库的密码
-d:指明数据库的名字
-c:指明collection的名字
-o:指明到要导出的文件名
-q:指明导出数据的过滤条件
-j, --numParallelCollections=  number of collections to dump in parallel (4 by default)
--oplog  备份的同时备份oplog
8.6.3 mongodump和mongorestore基本使用
# 1. 备份
## 1.1 全库备份
mkdir -p /mongodb/backup/full
mongodump  -uroot -p123456 --port 27017 --authenticationDatabase admin -o /mongodb/backup/full

## 1.2 备份oldboy库
mkdir  -p /mongodb/backup/oldboy
mongodump   -uroot -p123456 --port 27017 --authenticationDatabase admin -d oldboy -o /mongodb/backup/test

## 1.3 备份oldguo库下的log集合
mkdir -p /mongodb/backup/log
mongodump   -uroot -p123456 --port 27017 --authenticationDatabase admin -d oldboy -c log -o /mongodb/backup/log

## 1.4 压缩备份
mkdir -p /mongodb/backup/full1
mongodump   -uroot -p123456 --port 27017 --authenticationDatabase admin -o /mongodb/backup/full1 --gzip
mongodump   -uroot -p123456 --port 27017 --authenticationDatabase admin -d oldguo -o /mongodb/backup/ --gzip
mongodump   -uroot -p123456 --port 27017 --authenticationDatabase admin -d app -c vast -o /mongodb/backup/ --gzip

# 2. 恢复
## 从全备full1中的oldboy库恢复到oldboy1库中(如果备份加了--gzip,恢复也要加--gzip)
mongorestore   -uroot -p123456 --port 27017 --authenticationDatabase admin -d oldboy1   /mongodb/backup/full1/oldboy --gzip

## 2.1 从全备full1中dongkun库下log表恢复到test库下t1表
[mongod@db01 ]$ mongorestore   -uroot -p123456 --port 27017 --authenticationDatabase admin -d test -c t1  --gzip  /mongodb/backup/full1/dongkun/log.bson.gz

## 2.2 drop表示恢复的时候把之前的集合drop掉(危险,会把原有的数据清空在进行恢复)
$ mongorestore  -uroot -p123456 --port 27017 --authenticationDatabase admin -d oldboy --drop  /mongodb/backup/oldboy

8.7 mongodump和mongorestore高级企业应用(–oplog)

注意:这是replica set或者master/slave模式专用
–oplog
use oplog for taking a point-in-time snapshot
8.7.1 oplog介绍
在replica set中oplog是一个定容集合(capped collection),它的默认大小是磁盘空间的5%(可以通过–oplogSizeMB参数修改).

位于local库的db.oplog.rs,有兴趣可以看看里面到底有些什么内容。
其中记录的是整个mongod实例一段时间内数据库的所有变更(插入/更新/删除)操作。
当空间用完时新记录自动覆盖最老的记录。
其覆盖范围被称作oplog时间窗口。需要注意的是,因为oplog是一个定容集合,
所以时间窗口能覆盖的范围会因为你单位时间内的更新次数不同而变化。
想要查看当前的oplog时间窗口预计值,可以使用以下命令:

说明:
1. 相当于MySQL中国你的binlog,保存的时MongoDB修改类操作的日志
2. 他是一个定容集合,大小不变的表。
3. 默认大小可以用磁盘大小5%,可以通过oplogSizeMB参数指定
4. 单节点MongoDB没有oplog,存在于复制集中。
5. 可以通过以下命令监控是否够用
[mongod@db01 ~]$ mongo --port 28017 admin
my_repl:PRIMARY> rs.printReplicationInfo()
configured oplog size:   2048MB   ----> 集合大小
log length start to end: 3341713secs (928.25hrs) ----> 预计窗口覆盖时间
oplog first event time:  Wed Jul 13 2022 23:09:13 GMT+0800 (CST)
oplog last event time:   Sun Aug 21 2022 15:24:26 GMT+0800 (CST)
now:                     Sun Aug 21 2022 15:24:27 GMT+0800 (CST)

oplog什么时候可以被覆盖?相当于binlog什么时候可以被删除?
至少要预留MongoDB一个全备的周期大小。如果备份走的日志也可以(预计窗口覆盖时间之内拷走文件)。
如果没有启动可以启动以下:
mongod -f /mongodb/28017/conf/mongod.conf 
mongod -f /mongodb/28018/conf/mongod.conf 
mongod -f /mongodb/28019/conf/mongod.conf 
mongod -f /mongodb/28020/conf/mongod.conf
 
use local 
db.oplog.rs.find().pretty()
{
	"ts" : Timestamp(1657725073, 1),
	"t" : NumberLong(1),
	"h" : NumberLong(0),
	"v" : 2,
	"op" : "n",
	"ns" : "",
	"wall" : ISODate("2022-07-13T15:11:13.809Z"),
	"o" : {
		"msg" : "periodic noop"
	}
}
# 需要关注的内容:
"ts" : Timestamp(1553597844, 1) ---> GTID 操作的唯一标识,也具备幂等性,1553597844是时间戳以秒为单位,1代表在这个时间中发生的第几次操作来,唯一标识mongodb中某个操作
"ns" : 操作的对象
"op" : "n"  ---> 操作类型
"o"  : 具体的信息

# op值的含义
"i": insert
"u": update
"d": delete
"c": db cmd (库表的创建删除修改)
"n": NOTE 提示,提示的信息,不用管他

开始实验:

# 1. 登录到mongo集群
[mongod@db01 ~]$ mongo --port 28017 admin
# 2. 切换到test库
my_repl:PRIMARY> use test
# 3. 在test库中创建x表
my_repl:PRIMARY> db.createCollection("x");
{
	"ok" : 1,
	"$clusterTime" : {
		"clusterTime" : Timestamp(1661181270, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	},
	"operationTime" : Timestamp(1661181270, 1)
}
# 4. 在oplog.rs表中找到刚才创建表的记录
my_repl:PRIMARY> use local
switched to db local
my_repl:PRIMARY> db.oplog.rs.find({"op":"c"}).pretty();
{
	"ts" : Timestamp(1661181270, 1),
	"t" : NumberLong(17),
	"h" : NumberLong(0),
	"v" : 2,
	"op" : "c",
	"ns" : "test.$cmd",
	"ui" : UUID("599b02c8-3d8d-40de-ad66-802a79f9803d"),
	"wall" : ISODate("2022-08-22T15:14:30.121Z"),
	"o" : {
		"create" : "x",
		"idIndex" : {
			"v" : 2,
			"key" : {
				"_id" : 1
			},
			"name" : "_id_",
			"ns" : "test.x"
		}
	}
}
8.7.2 oplog企业级应用
(1)实现热备,在备份时使用–oplog选项
注:为了演示效果我们在备份过程,模拟数据插入
(2)准备测试数据
my_repl:PRIMARY> use oldboy
my_repl:PRIMARY> 
for(var i = 1 ;i < 100; i++) {
    db.foo.insert({a:i});
}
my_repl:PRIMARY> use local
my_repl:PRIMARY> db.oplog.rs.find({"op":"i"}).pretty()

oplog 配合mongodump实现热备
mkdir -p /mongodb/backup/opdata
mongodump --port 28017 --oplog -o /mongodb/backup/opdata
作用介绍:–oplog 会记录备份过程中的数据变化。会以oplog.bson保存下来
[mongod@db01 ~]$  ll /mongodb/backup/opdata/
drwxrwxr-x 2 mongod mongod  69 8月  22 23:48 admin
drwxrwxr-x 2 mongod mongod  47 8月  22 23:48 oldboy
-rw-rw-r-- 1 mongod mongod 110 8月  22 23:48 oplog.bson
drwxrwxr-x 2 mongod mongod  43 8月  22 23:48 test
oplog.bson是备份期间oplog的快照

恢复
mongorestore  --port 28017 --oplogReplay /mongodb/backup/opdata
# --drop删除原表数据,在进行恢复
mongorestore  --port 28017 --drop --oplogReplay /mongodb/backup/opdata

8.8 oplog高级应用

oplog高级应用
背景:每天23点全备,oplog恢复窗口为48小时
某天,上午10点world.t1 业务表被误删除。
恢复思路:
0、停应用
2、找测试库
3、恢复昨天晚上全备
4、截取全备之后到world.city误删除时间点的oplog,并恢复到测试库
5、将误删除表导出,恢复到生产库

恢复步骤:
模拟故障环境:
# 1、全备数据库
模拟原始数据
[mongod@db01 ~]$ mongo --port 28017 admin
my_repl:PRIMARY> use test
my_repl:PRIMARY> 
for(var i = 1 ;i < 20; i++) {
    db.t1.insert({a: i});
}
# 查看以下数据
my_repl:PRIMARY> db.t1.find()


全备: 
[mongod@db01 ~]$ rm -rf /mongodb/backup/*
[mongod@db01 ~]$ mongodump --port 28017 --oplog -o /mongodb/backup

–oplog功能:在备份同时,将备份过程中产生的日志进行备份
文件必须存放在/mongodb/backup下,自动命名为oplog.bson

再次模拟数据
my_repl:PRIMARY> use test
my_repl:PRIMARY> db.t2.insert({id:1})
my_repl:PRIMARY> db.t3.insert({id:2})

# 2、上午10点:删除test库下的t1表
10:00时刻,误删除
my_repl:PRIMARY> use test
my_repl:PRIMARY> db.t1.drop()
my_repl:PRIMARY> show tables;
# 在创建要给t4表
my_repl:PRIMARY> db.t4.insert({id:3})

3、备份现有的oplog.rs表(local库下的oplog.rs记录了所有的操作)
[mongod@db01 backup]$ mongodump --port 28017 -d local -c  oplog.rs  -o /mongodb/oplog
[mongod@db01 backup]$ cd /mongodb/oplog/local
[mongod@db01 backup]$ cp oplog.rs.bson /mongodb/backup/oplog.bson

4、截取oplog并恢复到drop之前的位置(因为local库下oplog.rs保存了所有的操作记录,只要包删除表的那条记录给去掉,然后在进行恢复,主要需要这个点Timestamp(1661184660, 1)相当于GTID)
更合理的方法:登陆到原数据库
[mongod@db01 ~]$ mongo --port 28017 admin
my_repl:PRIMARY> use local
my_repl:PRIMARY> db.oplog.rs.find({op:"c"}).pretty();
{
	"ts" : Timestamp(1661184660, 1),
	"t" : NumberLong(17),
	"h" : NumberLong(0),
	"v" : 2,
	"op" : "c",
	"ns" : "test.$cmd",
	"ui" : UUID("da4533e8-fc0e-4507-90d1-dc226ac6f5b1"),
	"o2" : {
		"numRecords" : 19
	},
	"wall" : ISODate("2022-08-22T16:11:00.190Z"),
	"o" : {
		"drop" : "t1"
	}
}
获取到oplog误删除时间点位置:
"ts" : Timestamp(1661184660, 1)

# 5. 恢复备份+应用oplog
# --oplogLimit 跳过不执行,t4表是在删除t1表创建的,因为只是跳过了删除t1表的操作,所以创建t4表操作也可以恢复
[mongod@db01 ~]$ mongorestore --port 28017 --oplogReplay --oplogLimit "1661184660:1" --drop /mongodb/backup

扩展命令: bsondump可以将bson格式的数据转换成json

8.9 分片集群的备份思路(了解)

方案一: 社区版,直接通过mongos进行备份 (实现整体的全备,不能实现单一分片的部分恢复)
缺点:只能单一的节点进行恢复,如果说某一个分片发生了故障,就类似于重构了,恢复的时间就会比较长,有好多个分片,不能通过恢复单个分片的部分数据来实现数据恢复的目的,只能进行全盘的进行恢复,因为备份出来就一个集合,相当于在一个节点备份出来的数据,如果恢复单个数据,因为有事分布的,所以只能全部恢复

手工备份步骤:
在这里插入图片描述

方案二: 企业版,专门备份工具Ops Manager(可以进行单一分片,集群当中所有关键点的一些备份。然后可以实现部分进行恢复)

方案三: 自己开发分布式备份系统

1. 你要备份什么
config server   存储了节点的配置信息,还有chunk的迁移情况,相当于是元数据
shard节点        真实的数据,文档
单独进行备份

2. 备份有什么困难和难题
(1) chunk迁移的问题
	人为控制在备份的时候,避开迁移的时间窗口
(2) shard节点之间数据不在统一时间点
	选业务量较少的时候,将configserver 各个shard节点摘除从节点(防止数据不一致问题,两个写请求向shard,一个1分钟,要给五分钟,可能导致时间不一致问题)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值