(1.5)mongodb备份恢复,mongodb备份还原,mongodb迁移

【1】备份恢复

(1.1)备份恢复工具介绍

应用场景总结:
(1)mongoexport/mongoimport:json csv 
1、异构平台迁移  mysql  <---> mongodb
2、同平台,跨大版本:mongodb 2  ----> mongodb 3
(2)mongodump/mongorestore Mongodb 的日常备份恢复时使用,mongodb内部常规运维比较多

(1.2)备份恢复工具下载

1、登录官网=》Products=>Community Server

 

  

 

2、Tools=》Mongodb Database Tools

  

【2】mongoexport/mongoimport 导入导出

(2.1)导出工具 mongoexport 

一般是 json 和 csv 格式

$ mongoexport --help  
参数说明:
-h:指明数据库宿主机的IP
-u:指明数据库的用户名
-p:指明数据库的密码
-d:指明数据库的名字
-c:指明collection的名字
-f:指明要导出那些列
-o:指明到要导出的文件名
-q:指明导出数据的过滤条件
--authenticationDatabase admin

1.单表备份至json格式
mongoexport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log -o /mongodb/log.json

注:备份文件的名字可以自定义,默认导出了JSON格式的数据。

2. 单表备份至csv格式
如果我们需要导出CSV格式的数据,则需要使用----type=csv参数:

mongoexport -uroot -proot123 --port 27017 --authenticationDatabase admin -d test -c log --type=csv -f uid,name,age,date  -o /mongodb/log.csv

(2.2)导入工具 mongoimport

一般是 json 和 csv 格式

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

//并行 数据恢复: 1.恢复json格式表数据到log1 mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log1 /mongodb/log.json
2.恢复csv格式的文件到log2 上面演示的是导入JSON格式的文件中的内容,如果要导入CSV格式文件中的内容,则需要通过--type参数指定导入格式,具体如下所示: 错误的恢复 注意: (1)csv格式的文件头行,有列名字 mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log2 --type=csv --headerline --file /mongodb/log.csv (2)csv格式的文件头行,没有列名字 mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log3 --type=csv -f id,name,age,date --file /mongodb/log.csv --headerline:指明第一行是列名,不需要导入。

(2.3)异构迁移案例

mysql   -----> mongodb  
world数据库下city表进行导出,导入到mongodb

(1)mysql开启安全路径
vim /etc/my.cnf   --->添加以下配置
secure-file-priv=/tmp

--重启数据库生效
/etc/init.d/mysqld restart

(2)导出mysql的city表数据
source /root/world.sql

select * from world.city into outfile '/tmp/city1.csv' fields terminated by ',';

(3)处理备份文件
desc world.city
  ID          | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name        | char(35) | NO   |     |         |                |
| CountryCode | char(3)  | NO   | MUL |         |                |
| District    | char(20) | NO   |     |         |                |
| Population

vim /tmp/city.csv   ----> 添加第一行列名信息

ID,Name,CountryCode,District,Population

(4)在mongodb中导入备份
mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d world  -c city --type=csv -f ID,Name,CountryCode,District,Population --file  /tmp/city1.csv

use world
db.city.find({CountryCode:"CHN"});

-------------
world共100张表,全部迁移到mongodb

select table_name ,group_concat(column_name) from columns where table_schema='world' group by table_name;

select * from world.city into outfile '/tmp/world_city.csv' fields terminated by ',';

select concat("select * from ",table_schema,".",table_name ," into outfile '/tmp/",table_schema,"_",table_name,".csv' fields terminated by ',';")
from information_schema.tables where table_schema ='world';

导入:
提示,使用infomation_schema.columns + information_schema.tables

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 ','  
optionally enclosed by '"' 
escaped by '"'   
lines terminated by '\r\n';

【3】mongodump/mongorestore/oplog

(3.1)mongodump

mongodump --help 查看帮助命令

  • -h,--host :代表远程连接的数据库地址,默认连接本地Mongo数据库;
  • --port:代表远程连接的数据库的端口,默认连接的远程端口27017;
  • -u,--username:代表连接远程数据库的账号,如果设置数据库的认证,需要指定用户账号;
  • -p,--password:代表连接数据库的账号对应的密码;
  • -d,--db:代表连接的数据库;
  • -c,--collection:代表连接数据库中的集合;
  • -o, --out:代表导出的文件输出目录;
  • -q, --query:代表查询条件;
  • -j,--numParallelCollections =要并行转储的集合数(默认为4)
  • --gzip,使用Gzip压缩存档;
  • --oplog,使用oplog进行时间点快照;
  • --authenticationDatabase,指定用户鉴定库

mongodump参数实践

#全库备份
mongodump -u -p --port 28020 --authenticationDatabase admin -o /tmp/backup
#备份指定的库,test库 mongodump
-u -p --port 28020 --authenticationDatabase admin -d test -o /tmp/backup
#备份test库下的customer集合 mongodump
-u -p --port 28020 --authenticationDatabase admin -d test -c customer -o /tmp/backup

压缩备份

#压缩备份单库
mongodump -u -p --port 28020 --authenticationDatabase admin -d test -o /tmp/backup --gzip
 
#压缩备份单表
mongodump -u -p --port 28020 --authenticationDatabase admin -d test -c customer -o /tmp/backup --gzip

 

(3.2)mongorestore恢复工具

mongorestore关键参数如下所示:

mongodump --help 查看帮助命令

  • -h,--host :代表远程连接的数据库地址,默认连接本地Mongo数据库;
  • --port:代表远程连接的数据库的端口,默认连接的远程端口27017;
  • -u,--username:代表连接远程数据库的账号,如果设置数据库的认证,需要指定用户账号;
  • -p,--password:代表连接数据库的账号对应的密码;
  • -d,--db:代表连接的数据库;
  • -c,--collection:代表连接数据库中的集合;
  • -o, --out:代表导出的文件输出目录;
  • --dir = <目录名称>输入目录
  • --drop导入前删除数据库中集合;
  • --gzip,解压Gzip压缩存档还原;
  • --oplog,重放oplog以基于时间点还原;
  • --oplogFile = <文件名>指定重播oplog的oplog文件
  • --authenticationDatabase,指定用户鉴定库

mongorestore参数实践

#单库恢复
mongorestore -u -p --port 28018 --authenticationDatabase admin -d test /tmp/backup/test


#恢复test库下的customer集合
mongorestore -u -p --port 28018 --authenticationDatabase admin -d test -c customer /tmp/backup/test/customer.bson

 

 

--drop参数实践恢复

恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,备份后添加修改的数据都会被删除,谨慎使用!!!

# 恢复单库
mongorestore -u -p --port 28018 --authenticationDatabase admin -d test --drop /tmp/backup/test
 
# 恢复单表
mongorestore -u -p --port 28018 --authenticationDatabase admin -d test -c customer --drop /tmp/backup/test/customer.bson

--gzip参数实践恢复

mongorestore -u -p --port 28018 --authenticationDatabase admin --gzip /tmp/backup

 

(3.3)MongoDB中的oplog

3.1 什么是oplog

  • 当Primary进行写操作的时候,会将这些写操作记录写入Primary的Oplog中,而后Secondary会将Oplog 复制到本机并应用这些操作,从而实现Replication的功能。
  • 同时由于其记录了Primary上的写操作,故还能将其用作数据恢复。
  • 可以简单的将其视作Mysql中的binlog。
  • oplog为replica set或者master/slave模式专用(standalone模式运行mongodb并不推荐)--新消息频道

3.2 oplog相关的操作

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

oplog的位置:

oplog在local库: local.oplog
master/slave 架构下:local.oplog.$main;
replica sets 架构下:local.oplog.rs

 

oplog时间窗口覆盖时间

  1.  easydb:PRIMARY> rs.printReplicationInfo()
  2.  configured oplog size: 2048MB <--集合大小
  3.  log length start to end: 524592secs (145.72hrs) <--预计窗口覆盖时间
  4.  oplog first event time: Fri Jan 08 2021 18:30:18 GMT+0800 (CST)
  5.  oplog last event time: Thu Jan 14 2021 20:13:30 GMT+0800 (CST)
  6.  now: Thu Jan 14 2021 20:13:35 GMT+0800 (CST)

查看oplog内容

 easydb:PRIMARY> use local
 easydb:PRIMARY> db.oplog.rs.find().pretty()
 {
 "ts" : Timestamp(1610101818, 1),
 "h" : NumberLong("-124421688313536398"),
 "v" : 2,
 "op" : "n",
 "ns" : "",
 "wall" : ISODate("2021-01-08T10:30:18.329Z"),
 "o" : {
 "msg" : "initiating set"
 }
 }

 

3.3 oplog数据结构

下面来分析一下oplog中字段的含义,通过下面的命令取出一条oplog:

db.oplog.rs.find().skip(1).limit(1).toArray()

 easydb:PRIMARY> use local
 switched to db local
 easydb:PRIMARY> db.oplog.rs.find().skip(1).limit(1).toArray()
 [
 {
 "ts" : Timestamp(1610101831, 1),
 "t" : NumberLong(1),
 "h" : NumberLong("-5190685117971188188"),
 "v" : 2,
 "op" : "n",
 "ns" : "",
 "wall" : ISODate("2021-01-08T10:30:31.356Z"),
 "o" : {
 "msg" : "new primary"
 }
 }
 ]

 

  • ts: 8字节的时间戳,由4字节unix timestamp + 4字节自增计数表示。这个值很重要,在选举(如master宕机时)新primary时,会选择ts最大的那个secondary作为新primary
  • op:1字节的操作类型
    • "i": insert
    • "u": update
    • "d": delete
    • "c": db cmd
    • "db":声明当前数据库 (其中ns 被设置成为=>数据库名称+ '.')
    • "n": no op,即空操作,其会定期执行以确保时效性
  • ns:操作所在的namespace
  • o:操作所对应的document,即当前操作的内容(比如更新操作时要更新的的字段和值)
  • o2: 在执行更新操作时的where条件,仅限于update时才有该属性

3.4 --oplog参数说明

mongodump --oplog参数说明

  • 该参数的主要作用是在导出的同时生成一个oplog.bson文件,存放在你开始进行dump到dump结束之间所有的oplog。
  • oplog 官方说明: Replica Set Oplog — MongoDB Manual
  • [root@mysql02 ~]# mongodump --help
    --oplog use oplog for taking a point-in-time snapshot

     

复制

mongorestore --oplog参数说明

参数

参数说明

--oplogReplay

重放oplog.bson中的操作内容

--oplogLimit

与--oplogReplay一起使用时,可以限制重放到指定的时间点

3.5 mongodump使用--oplog参数备份

首先我们在mongodb中模拟一个不断有插入操作的集合foo

  1.  use test
  2.  for(var i = 0; i < 10000; i++) {
  3.  db.foo.insert({a: i});
  4.  }

然后在插入过程中模拟一次mongodump全备,并添加--oplog参数

[root@mysql02 ~]# mongodump -u -p --port 28018 --authenticationDatabase admin --oplog -o /tmp/backup
 2021-01-14T20:51:15.254+0800 writing admin.system.version to
 2021-01-14T20:51:15.255+0800 done dumping admin.system.version (1 document)
 2021-01-14T20:51:15.255+0800 writing test.foo to
 2021-01-14T20:51:15.474+0800 done dumping test.foo (1701 documents)
 2021-01-14T20:51:15.483+0800 writing captured oplog to
 2021-01-14T20:51:15.509+0800 dumped 73 oplog entries
 
[root@mysql02 ~]# ll /tmp/backup
 总用量 12
 drwxr-xr-x 2 root root 69 1月 14 20:51 admin
 -rw-r--r-- 1 root root 10804 1月 14 20:51 oplog.bson
 drwxr-xr-x 2 root root 47 1月 14 20:51 test
   从dump开始到结束的时间系统将记录所有的oplog到oplog.bson文件中

 

注意:--oplog选项只对全库导出有效,所以不能指定-d选项。

3.6 mongorestore使用--oplog参数恢复

[root@mysql02 ~]# mongorestore -u -p --port 28018 --authenticationDatabase admin --oplogReplay --drop /tmp/backup

2021-01-14T21:13:52.134+0800 preparing collections to restore from
2021-01-14T21:13:52.144+0800 reading metadata for test.foo from /tmp/backup/test/foo.metadata.json
2021-01-14T21:13:52.199+0800 restoring test.foo from /tmp/backup/test/foo.bson
2021-01-14T21:13:52.291+0800 no indexes to restore
2021-01-14T21:13:52.291+0800 finished restoring test.foo (1701 documents) <--表示test.foo集合中恢复了1701个文档 2021-01-14T21:13:52.291+0800 replaying oplog <--表示重放了oplog中的所有操作 2021-01-14T21:13:52.407+0800 done easydb:PRIMARY> db.foo.count() 1771 <--所以实际比1701个多,因为应用了oplog中的数据

 

复制

这就是 oplog 配合 mongodump 实现热备功能

(3.4)利用oplog实现任意时间点数据恢复

oplog有两种来源:

  • mongodump时加上--oplog选项,自动生成的oplog,这种方式的oplog直接 --oplogReplay 就可以恢复
  • 单独备份获取的oplog

例如:

mongodump  --port 28021 -d local -c oplog.rs

复制

4.1 模拟一个持续写入的生产环境

easydb:PRIMARY> use test
switched to db test
 
easydb:PRIMARY> for(i=0;i<30000;i++){ db.easydb.insert({"id":i,"name":"easydb.net","age":18,"date":new Date()}); }
WriteResult({ "nInserted" : 1 })

 

4.2 插入数据的同时备份

[root@mysql02 ~]# mongodump -u -p --port 28018 --authenticationDatabase admin --oplog -o /tmp/backup
 
2021-01-15T11:46:14.449+0800 writing admin.system.version to
 
2021-01-15T11:46:14.451+0800 done dumping admin.system.version (1 document)
 
2021-01-15T11:46:14.452+0800 writing test.easydb to
 
2021-01-15T11:46:15.799+0800 done dumping test.easydb (20154 documents)
 
2021-01-15T11:46:15.805+0800 writing captured oplog to
 
2021-01-15T11:46:15.991+0800 dumped 1601 oplog entries

 

 

4.3 备份完成后模拟一个错误的操作

easydb:PRIMARY> use test
switched to db test
 
 
easydb:PRIMARY> show collections
easydb
 
easydb:PRIMARY> db.dropDatabase()
{
"dropped" : "test",
"ok" : 1,
"operationTime" : Timestamp(1610682482, 2),
"$clusterTime" : {
"clusterTime" : Timestamp(1610682482, 2),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}

 

4.4 切割全备里的oplog,找出上次全备最后一个时间的数据

 [root@mysql02 ~]# bsondump /tmp/backup/oplog.bson > /tmp/oplog.json
 2021-01-16T17:28:56.252+0800 417 objects found
 [root@mysql02 ~]# tail -1 /tmp/oplog.json
 {"ts":{"$timestamp":{"t":1610789118,"i":416}},"t":{"$numberLong":"6"},"h":{"$numberLong":"8277197316656995929"},"v":2,"op":"i","ns":"test.easydb","ui":{"$binary":"JEUrQxOWS6Gw8vfPIetrqQ==","$type":"04"},"wall":{"$date":"2021-01-16T09:25:18.435Z"},"o":{"_id":{"$oid":"6002b0fe4994bdfbd2b0747e"},"id":17511.0,"name":"easydb.net","age":18.0,"date":{"$date":"2021-01-16T09:25:18.443Z"}}}
 {"t":1610789118,"i":416}就是上一次全备最后的时间戳

 

4.5 导出上一次全备以后的增量数据

 mongodump -u -p --port 28018 --authenticationDatabase admin -d local -c oplog.rs -q '{ts:{$gt:Timestamp(1610789118,416)}}' -o /tmp/oplog
#这里填的是我们上一步截取的时间戳

 

4.6 恢复最近一次全备的数据

 mongorestore -u -p --port 28018 --authenticationDatabase admin --oplogReplay /tmp/backup
  easydb:PRIMARY> use test
 switched to db test
 easydb:PRIMARY> db.easydb.count()
 17512
 检查全备恢复了多少条数据

 

4.7 截取备份出来增量的oplog,找到误删库的时间点(limt)

  • 删库语句的上一个oplog时间戳为终点。
[root@mysql02 ~]# bsondump /tmp/oplog/local/oplog.rs.bson | grep -C 5 dropDatabase
{"ts":{"$timestamp":{"t":1610789163,"i":1}},"t":{"$numberLong":"6"},"h":{"$numberLong":"-8852159408511820267"},"v":2,"op":"n","ns":"","wall":{"$date":"2021-01-16T09:26:03.551Z"},"o":{"msg":"periodic noop"}}
{"ts":{"$timestamp":{"t":1610789168,"i":1}},"t":{"$numberLong":"6"},"h":{"$numberLong":"-8231808943143165392"},"v":2,"op":"c","ns":"test.$cmd","ui":{"$binary":"JEUrQxOWS6Gw8vfPIetrqQ==","$type":"04"},"wall":{"$date":"2021-01-16T09:26:08.735Z"},"o":{"drop":"easydb"}}
 
2021-01-16T17:51:45.426+0800 12587 objects found
 
{"ts":{"$timestamp":{"t":1610789168,"i":2}},"t":{"$numberLong":"6"},"h":{"$numberLong":"-1802663680461751854"},"v":2,"op":"c","ns":"test.$cmd","wall":{"$date":"2021-01-16T09:26:08.807Z"},"o":{"dropDatabase":1}}
{"ts":{"$timestamp":{"t":1610789183,"i":1}},"t":{"$numberLong":"6"},"h":{"$numberLong":"7216379125886047426"},"v":2,"op":"n","ns":"","wall":{"$date":"2021-01-16T09:26:23.551Z"},"o":{"msg":"periodic noop"}}
{"t":1610789168,"i":1}

  

将过滤出来的Unix时间戳进行转换,再次确认是不是误操作的时间点

4.8 复制增量的oplog到备份目录,重命名为oplog.bson,将原来的oplog.bson覆盖

cp /tmp/oplog/local/oplog.rs.bson /tmp/backup/oplog.bson

4.9 将增量的oplog进行恢复,添加之前找到的误删除的点(limt)

mongorestore -u -p --port 28018 --authenticationDatabase admin --oplogReplay --oplogLimit "1610789168:1" /tmp/backup
easydb:PRIMARY> db.easydb.count()

30000
 
再次检查,发现30000条数据已经全部恢复

4.10 把恢复后的数据再做一次全备,至此一次恢复就完成了

 

 

【参考文档】

【3】转自:https://blog.csdn.net/larance001/article/details/126598891

 

posted @ 2022-05-05 17:52  郭大侠1  阅读(151)  评论(0编辑  收藏  举报