三、Mongodb备份和恢复、异构迁移

1 备份恢复工具介绍

  1. mongoexport/mongoimport,导入/导出的是JSON格式或CSV格式
  2. mongodump/mongorestore,导入/导出的是BSON格式,常用!

JSON可读性强但体积较大,BSON是JSON的二进制文件,体积小但对人类几乎没有可读性。

在一些mongodb版本之间,BSON格式可能会随版本不同而有所不同,所以不同版本之间用mongodump/mongorestore可能不会成功,具体要看版本之间的兼容性。当无法使用BSON进行跨版本的数据迁移的时候,使用JSON格式即mongoexport/mongoimport是一个可选项。不推荐进行跨版本的mongodump/mongorestore

应用场景总结:

  • 跨版本的mongodb数据导入导出,或异构平台的数据迁移,只能使用mongoexport/mongoimport
  • 日常备份恢复,使用 mongodump/mongorestore

2 mongoexport和mongoimport

2.1 mongoexport

参数说明

-h                          指明数据库宿主机的IP
-u                          指明数据库的用户名
-p                          指明数据库的密码
-d                          指明数据库的名字
-c                          指明collection的名字
-f                          指明要导出哪些列
-o                          指明要导出的文件名
-q                          指明导出数据的过滤条件
--authenticationDatabase    指明验证库
--type                      指明导出文件类型,默认是json,可以配置为CSV

例子:备份bigsky库的log集合,认证库是admin

#json格式备份
mongoexport -u root -p 123 -d bigsky -c log -o /tmp/log.json --authenticationDatabase admin
#CSV格式备份,需要-f指定备份哪些列
mongoexport -u root -p 123 -d bigsky -c log -o /tmp/log.csv --authenticationDatabase admin --type CSV -f uid

2.2 mongoimport

参数说明

-h                          指明数据库宿主机的IP
-u                          指明数据库的用户名
-p                          指明数据库的密码
-d                          指明数据库的名字
-c                          指明collection的名字
-f                          指明要导入哪些列,多个列用","分割
-j                          并发导入,使用几个cpu,默认是1
--drop                      导入时删除原集合中的数据
--authenticationDatabase    指明验证库

例子:导入到aaa库的test集合,认证库是admin

#json导入
mongoimport -u root -p 123 -d aaa -c test --authenticationDatabase admin log.json
#CSV导入,当头行是列名时,需要加 --headerline参数
mongoimport -u root -p 123 -d aaa -c test1 --type CSV --headerline --authenticationDatabase admin log.csv
#CSV导入,当没有列名时,需要加 -f指定导入哪列
mongoimport -u root -p 123 -d aaa -c test2 --type CSV -f uid --authenticationDatabase admin log.csv

2.3 异构迁移

通过CSV格式的文件进行迁移,mysql和mongodb导出支持的CSV格式稍有不同,中间需要更改表的格式

mongodb CSV格式

mongodb格式第一行为列名,行数据用,分隔
mysql CSV格式

mysql导出的CSV不包含列名,行数据用\t分隔

2.3.1 mysql到mongodb

2.3.1.1 mysql导出数据

要导出的数据


由于mysql默认导出的格式与mongodb不一样,导出时需要更改格式,使用fields terminated by ','参数

select id,sname,sage from test.t1 into outfile '/tmp/backup.csv' fields terminated by ',';

效果如下:


2.3.1.2 mongodb导入数据

由于mysql导出时不带列名,mongodb导入时需要加-f参数指定列名

mongoimport -u root -p 123 -d test -c t1 --type CSV -f id,sname,sage --authenticationDatabase admin /tmp/backup.csv

2.3.2 mongodb到mysql

2.3.2.1 mongodb导出数据

要导出的数据



导出CSV格式数据

mongoexport -u root -p 123 -d test -c t1 -o /tmp/t1.csv --authenticationDatabase admin --type CSV -f id,sname,sage

导出的数据如下


2.3.2.2 mysql导入数据

创建跟mongodb导出数据列名一样的表

CREATE TABLE `t2` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '学号',
  `sname` varchar(255) NOT NULL COMMENT '姓名',
  `sage` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '年龄',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

在mysql中导入数据

LOAD DATA LOCAL INFILE '/tmp/t1.csv' INTO TABLE t2 CHARACTER SET utf8 
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' (`id`,`sname`,`sage`);

3 mongodump和mongorestore

mongodump能够在Mongodb运行时进行备份,它的工作原理是对运行的Mongodb做查询,然后将所有查到的文档写入磁盘。

存在的问题:
使用Mongodump产生的备份不一定是数据库的实时快照,如果在备份时对数据库进行了写入操作,则备份出来的文件可能不完全和Mongodb实时数据相等。另外在备份时可能会对其他客户端性能产生影响。

3.1 mongodump

3.1.1 命令参数

mongodump --help
参数说明
-h                          指明数据库宿主机的IP
-u                          指明数据库的用户名
-p                          指明数据库的密码
-d                          指明数据库的名字
-c                          指明collection的名字
-o                          指明要导出的文件名
-q                          指明导出数据的过滤条件
-j                          并发导出,使用几个cpu,默认是1
--oplog                     同时备份oplog,配置复制集时使用
--authenticationDatabase    指明验证库

3.1.2 全库备份

mkdir /mongodb/backup
mongodump -uroot -p123 --port 27017 --authenticationDatabase admin -o /mongodb/backup

备份后每个库生成一个目录,每个集合生成两个文件:一个.bson文件、一个.metadata.json文件


.bson文件可以用bsondump命令查看并导出成json格式,之后可以用mongoimport工具还原

bsondump test/t1.bson 
{"_id":{"$oid":"60ab580444c9cbde02a3b130"},"id":{"$numberInt":"1"},"sname":"aaa","sage":{"$numberInt":"10"}}
{"_id":{"$oid":"60ab580444c9cbde02a3b131"},"id":{"$numberInt":"2"},"sname":"bbb","sage":{"$numberInt":"11"}}
{"_id":{"$oid":"60ab580444c9cbde02a3b132"},"id":{"$numberInt":"3"},"sname":"ccc","sage":{"$numberInt":"12"}}

3.1.3 备份单库

备份test单库

mongodump -uroot -p123 --port 27017 --authenticationDatabase admin -d test -o /mongodb/backup

3.1.4 备份单集合

备份test库的t1集合

mongodump -uroot -p123 --port 27017 --authenticationDatabase admin -d test -c t1 -o /mongodb/backup

3.1.5 压缩备份

加入--gzip参数进行压缩,会对每个bsonjson文件进行gz压缩

mongodump -uroot -p123 --port 27017 --authenticationDatabase admin -o /mongodb/backup --gzip

3.2 mongorestore

3.2.1 常用参数

mongorestore --help
参数说明
-h                          指明数据库宿主机的IP
-u                          指明数据库的用户名
-p                          指明数据库的密码
-d                          指明数据库的名字
-c                          指明collection的名字
-j                          并发导出,使用几个cpu,默认是1
--drop                      恢复的时候把之前的集合drop掉10.207.42.0/
--authenticationDatabase    指明验证库
--oplogReplay               同时恢复oplog中的内容
--oplogLimit                <seconds>[:ordinal]恢复到指定的时间戳之前

3.2.2 全备恢复

mongorestore -uroot -p123 --port 27017 --authenticationDatabase admin /mongodb/backup

3.2.3 单库恢复

备份文件的目录需定位到备份出来的库目录,本例恢复test库,指向的备份文件目录为/mongodb/backup/test

mongorestore -uroot -p123 --port 27017 --authenticationDatabase admin -d test --gzip /mongodb/backup/test

3.2.4 单集合恢复

备份文件的目录需定位到备份出来的集合文件名,本例恢复test库的t5集合,指向的备份文件名为/mongodb/backup/test/t5.bson.gz

mongorestore -uroot -p123 --port 27017 --authenticationDatabase admin -d test -c t5 --gzip /mongodb/backup/test/t5.bson.gz

4 oplog应用

4.1 介绍

在replica set中oplog是一个定容集合(capped collection),它的默认大小是磁盘空间的5%,可以通过--oplogSizeMB参数修改。
位于local库的db.oplog.rs,其中记录的是整个mongod实例一段时间内数据库的所有变更(插入/更新/删除)操作,类似于mysql binlog。当空间用完时新记录自动覆盖最老的记录。

oplog的覆盖范围为oplog的时间窗口,因为oplog是一个定容集合,所以时间窗口能覆盖的范围会因为单位时间内的更新次数不同而变化。

4.2 db.oplog.rs中的内容

{
    "op" : "n",
    "ns" : "",
    "o" : {
        "msg" : "periodic noop"
    },
    "ts" : Timestamp(1620637412, 1),
    "t" : NumberLong(1),
    "wall" : ISODate("2021-05-10T09:03:32.359Z"),
    "v" : NumberLong(2)
}

重点关注参数:
"ts":时间戳,()中前一个数是时间,后一个数是当时发生的第几个事件
"op":进行操作的类型,"n"提示类的、"i"insert、"u"update、"d"delete、"c"db cmd(删库建库,删表建表...)

4.3 oplog大小及覆盖窗口

查看当前配置的大小rs.printReplicationInfo()

my_repl:PRIMARY>    rs.printReplicationInfo()
configured oplog size:   2048MB
log length start to end: 2422018secs (672.78hrs)
oplog first event time:  Mon May 10 2021 17:01:20 GMT+0800 (CST)
oplog last event time:   Mon Jun 07 2021 17:48:18 GMT+0800 (CST)
now:                     Mon Jun 07 2021 17:48:27 GMT+0800 (CST)

参数解释:
configured oplog size:               当前配置的大小
log length start to end:             预估的覆盖时间

因为log length start to end是预估的时间,所以生产中一般在覆盖时间内对db.oplog.rs表进行定期全备。

4.4 带有oplog的备份、恢复

4.4.1 mongodump

使用mongodump备份时,可以将备份过程中数据库的操作通过oplog备份出,添加--oplog参数

mongodump -uroot -p123 --port 28017 --authenticationDatabase admin --oplog  -o /mongodb/backup

4.4.2 mongorestore

由于复制集默认只有主节点有写入权限,所以恢复的时候要连接主节点,添加--oplogReplay参数

mongorestore -uroot -p123 --port 28018 --authenticationDatabase admin --oplogReplay /mongodb/backup

5 oplog备份恢复案例

5.1 模拟全备+oplog故障恢复

5.1.1 环境准备

创建bigsky库和t1表、t2表

use bigsky
db.t1.insert([{"id":1},{"id":2}])
db.t2.insert({"id":1})

进行全备

mongodump --port 28018 --oplog -o /mongodb/backup/

5.1.2 模拟插入数据和删库操作

对t2表继续插入数据

db.t2.insert([{"id":2},{"id":3}])

删库

use bigsky
db.dropDatabase()

5.1.3 定位删除操作的时间戳

use local
db.oplog.rs.find({"op":"c"}).pretty()

删库时,数据库内部的操作顺序是先删表再删库,以此为依据来定位删除的起始时间,起始时间是1623141134, 1

5.1.4 备份出全量oplog

mongodump --port 28018 -d local -c oplog.rs -o /mongodb/oplog/

5.1.5 使用全量oplog替换全备的oplog

mv /mongodb/oplog/local/oplog.rs.bson /mongodb/backup/oplog.bson

5.1.6 mongorestore恢复到删除操作之前

--oplogLimit "1623141134:1"恢复到删除操作之前

mongorestore --port 28018 --oplogReplay --oplogLimit "1623141134:1" /mongodb/backup/ --drop

6 分片集群备份思路

6.1 需要备份的服务

config server
shard节点

6.2 备份的困难和问题

  1. chunk迁移问题
    人为控制备份的时间,避开balancer开启chunk迁移的时间窗口。保证备份出来的config server中记录的分片信息和shard中的分片信息一致。
  2. shard节点之间的数据不在同一时间点
    选择业务量较少的时间,将shard集中的从节点剔除复制集,备份从节点数据后,再将从节点加回集群。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容