MognoDB备份与恢复

mongoexport/mongoimport

mongoexport用于导出MongoDB实例中的数据,支持JSON和CSV格式。而mongoimport则提供相反的导入功能。Mongoexport/mongoimport采用严格模式表示。mongoexport需要对数据库进行读访问,因此连接用户至少要有数据库的read角色。mongoimport仅支持UTF-8编码的文件,且连接用户要有readwrite的数据库角色

mongoexport

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
[root@t-zabbix-p-szzb ~]# mongoexport --help
Usage:
    mongoexport <options>

Export data from MongoDB in CSV or JSON format.

See http://docs.mongodb.org/manual/reference/program/mongoexport/ for more information.

general options:
            --help                                      查看帮助
            --version                                   查看工具版本并退出

verbosity options:
    -v, --verbose=<level>                               增加详细日志的等级 (通过多次-v选项来增加输出详细程度,例如-vvvvv)
            --quiet                                     以静默方式运行

connection options:
    -h, --host=<hostname>                               连接的主机名 
            --port=<port>                               连接对应的端口
(连接副本集:-h <replsetName>/<host1:port>,<host2:port>)

ssl options:
            --ssl                                       连接到启用了TSL/SSL支持的mongod或mongos
            --sslCAFile=<filename>                      指定.pem根证书文件
            --sslPEMKeyFile=<filename>                  指定.pem包含的TSL/SSL证书和密钥文件
            --sslPEMKeyPassword=<password>              指定解密证书密钥文件的密码
            --sslCRLFile=<filename>                     指定.pem包含证书吊销列表的文件
            --sslAllowInvalidCertificates               绕过服务器的证书检查,并允许使用无效证书
            --sslAllowInvalidHostnames                  禁用TSL/SSL证书中主机名的验证
            --sslFIPSMode                               使用已安装的OPENSSL库的FIPS模式

authentication options:
    -u, --username=<username>                           登录用户名
    -p, --password=<password>                           登录密码
            --authenticationDatabase=<database-name>    用户对应的认证数据库
            --authenticationMechanism=<mechanism>       验证机制,默认为SCRAM-SHA-1

namespace options:
    -d, --db=<database-name>                            指定数据库名称
    -c, --collection=<collection-name>                  指定集合名称

uri options:
            --uri=mongodb-uri                           URI连接串(mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]])

output options:
    -f, --fields=<field>[,<field>]*                     指定要包含在导出中的字段,使用逗号分割
            --fieldFile=<filename>                      将要包含的字段先记录在文件中,一行一个字段。仅对--type为CSV
            --type=<type>                               输出的文件类型(default: json)
    -o, --out=<filename>                                输出的文件。如果未指定则写入标准输出
            --jsonArray                                 将导出的内容写入单个JSON数组
            --pretty                                    格式美化输出
            --noHeaderLine                              导出类型为CSV格式时,忽略第一行字段名

querying options:
    -q, --query=<json>                                  查询条件
            --queryFile=<filename>                      JSON格式的查询文件
    -k, --slaveOk                                       设置从节点可读,默认为true
            --readPreference=<string>|<json>            设置读首选项,默认为primary
            --forceTableScan                            强制直接扫描数据存储而非_id索引遍历
            --skip=<count>                              跳过部分文档
            --limit=<count>                             指定导出的最大文档数
            --sort=<json>                               指定导出结果的排序。如果不存在支持排序的索引,则结果必须小于32M

示例

使用–fields选项,导出CSV格式的数据

1
mongoexport --db users --collection contacts --type = csv --fields nameaddress --out /opt/backups/contacts.csv

导出JSON格式

1
mongoexport --db sales --collection contacts --out contacts.json

通过身份验证导出远程数据

1
mongoexport --host mongodb1.example.net --port 37017 --username user --password "pass"-- collection contacts --db marketing --out mdb1-examplenet.json

导出查询结果

1
mongoexport --db sales --collection contacts --query '{"field":1}'

mongoimport

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
[root@t-luhxdb01-p-szzb ~]# mongoimport --help
Usage:
    mongoimport <options> <file>

Import CSV, TSV or JSON data into MongoDB. If no file is provided, mongoimport reads from stdin.

See http://docs.mongodb.org/manual/reference/program/mongoimport/ for more information.

general options:
            --help                                      查看帮助
            --version                                   查看工具

verbosity options:
    -v, --verbose=<level>                               增加详细日志的等级 (通过多次-v选项来增加输出详细程度,例如-vvvvv)
            --quiet                                     静默的方式执行

connection options:
    -h, --host=<hostname>                               连接的主机名 
            --port=<port>                               连接对应的端口
(连接副本集:-h <replsetName>/<host1:port>,<host2:port>)

ssl options:
            --ssl                                       连接到启用了TSL/SSL支持的mongod或mongos
            --sslCAFile=<filename>                      指定.pem根证书文件
            --sslPEMKeyFile=<filename>                  指定.pem包含的TSL/SSL证书和密钥文件
            --sslPEMKeyPassword=<password>              指定解密证书密钥文件的密码
            --sslCRLFile=<filename>                     指定.pem包含证书吊销列表的文件
            --sslAllowInvalidCertificates               绕过服务器的证书检查,并允许使用无效证书
            --sslAllowInvalidHostnames                  禁用TSL/SSL证书中主机名的验证
            --sslFIPSMode                               使用已安装的OPENSSL库的FIPS模式

authentication options:
    -u, --username=<username>                           登录用户名
    -p, --password=<password>                           登录密码
            --authenticationDatabase=<database-name>    用户对应的认证数据库
            --authenticationMechanism=<mechanism>       验证机制,默认为SCRAM-SHA-1

namespace options:
    -d, --db=<database-name>                            指定数据库名称
    -c, --collection=<collection-name>                  指定集合名称
uri options:
            --uri=mongodb-uri                           URI连接串(mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]])

input options:
    -f, --fields=<field>[,<field>]*                     在导入的CSV中第一行不存在字段名时,用逗号分割字段名
            --fieldFile=<filename>                      在导入的CSV中第一行不存在字段名时,以文件的形式每行设置一个字段名
            --file=<filename>                           要导入的数据文件位置及名称
            --headerline                                CSV中第一行表示字段名
            --jsonArray                                 将多个文档导入单个JSON数组,仅限不大于16M
            --parseGrace=<grace>                        处理类型错误的方式 : autoCast, skipField, skipRow, stop (defaults to 'stop')
            --type=<type>                               指定要导入的文件类型(default: json)
            --columnsHaveTypes                          指定fields中字段对应的类型(auto(),binary(<arg>),boolean(),data(<arg>),data_go(arg),data_ms(<arg>),data_oracle(<arg>),double(),int32(),int64(),string())

ingest options:
            --drop                                      导入前删除对应集合
            --ignoreBlanks                              忽略CSV中的空白字段
            --maintainInsertionOrder                    按照导入文件中的顺序插入,否则会任意顺序插入
    -j, --numInsertionWorkers=<number>                  并行度(default: 1)
            --stopOnError                               在遇到错误时停止操作
            --mode=[insert|upsert|merge]                指定导入过程中如何文档冲突(defaults:insert,upset,merge)
            --upsertFields=<field>[,<field>]*           当使用upset或者merge时,以逗号分割字段
            --writeConcern=<write-concern-specifier>    写入数据库时的写入参数,等价于mongo shell中的-w参数。Defaults:majority
            --bypassDocumentValidation                  导入时绕过文档验证

示例

简单导入

1
mongoimport --db users --collection contacts --file contacts.json

导入期间合并匹配文档

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
DB:
    {
      "_id" : ObjectId("580100f4da893943d393e909"),
      "name" : "Crystal Duncan",
      "region" : "United States",
      "email" : "crystal@example.com"
    }
    
FILE:
    {
      "_id" : ObjectId("580100f4da893943d393e909"),
      "username" : "crystal",
      "email": "crystal.duncan@example.com",
      "likes" : [ "running", "pandas", "software development" ]
    }
    
Merge:
    mongoimport -c people -d example --mode merge --file people-20160927.json
    
Request:
    {
      "_id" : ObjectId("580100f4da893943d393e909"),
      "name" : "Crystal Duncan",
      "region" : "United States",
      "email" : "crystal.duncan@example.com",
      "username" : "crystal",
      "likes" : [
            "running",
            "pandas",
            "software development"
        ]
    }

使用指定字段类型导入

1
mongoimport --db users --collection contacts --type csv --columnsHaveTypes --fields "name.string(),birthdate.date(2006-01-02),contacts.boolean(),followerCount.int32(),user thumbnail.binary(base64)" - file /example/file.csv

忽略空白字段

1
mongoimport --db users --collection contacts --type csv --file /example/data.csv --ignoreBlanks

mongodump/mongorestore

mongodump

Mongodump是一个用于创建数据库内容的二进制导出程序,mongodump可以从任意mongod或mongos实例导出数据。Mongodump将排除local数据库的内容,在3.4中添加了对只读视图的支持,默认情况仅捕获视图的原数据,要在视图中捕获文档,请使用–viewsAsCollections

选项 说明
–host 参数的选择会影响连接副本集时的读取首选项,如果以replset_name/host1:port1,host2:port2的方式连接则从primary中读取,如果以host1:port1,host2:port2的方式读取则从nearest读取
–uri 指定可解析的URI连接字符串连接到MongoDB,–uri “mongodb:// [username:password @] host1 [:port1] [,host2 [:port2],… [,hostN [:portN]]] [/ [database] [?options]]”
–port 连接端口,不能与URI共用
–username 指定连接用户,与–password和–authenticationDatabase一起使用
-db 指定要备份的数据库,未指定则表示所有数据库
–collection 指定要备份的集合,未指定则表示所有集合
–queryFile 指定包含JSON文档的文件路径,该文件作为查询过滤器,用于限制mongodb输出的文档
–readPreference 指定读取首选项,当连接到一个mongos或者副本集默认primary优先,否则nearest
–gzip 压缩输出
–out 指定mongodump输出文件的保存路径
–oplog 导出oplog集合,包含mongodump过程中的oplog记录
–excludeColleciton 排除指定集合,也可以使用–excludeCollectionsWithPrefix排除具有指定前缀的所有集合
–archive 将输出写入单个存档文件或标准输出

示例

过滤指定集合

1
mongodump  --db test --excludeCollection=users --excludeCollection=salaries

将存档输出到标准输出

1
mongodump --archive --db test --port 27017  | mongorestore --archive --port 27018

mongorestore

mongorestore是插入的形式,可以创建新的数据库也可以将数据追加到现有数据库,如果将文档还原到现有数据库并且集合和现有文档_id相同,则mongorestore不会覆盖这些文档

选项 说明
–dir 指定转储目录,不能同时指定path参数和–archive选项
–archive 从归档文件或标准输入(stdin)恢复
path mongorestore命令的最后一个参数是目录路径。此参数指定要从中还原的数据库转储的位置
–gzip 要从包含压缩文件的转储目录进行还原,请mongorestore使用新–gzip选项运行
–numInsertionWorkersPerCollection 指定每个集合并发运行的插入工作器数
–noIndexRestore 阻止mongorestore恢复和构建相应mongodump输出中指定的索引
–oplogReplay 还原数据库转储后,从bson文件重放oplog条目
–oplogLimit 阻止mongorestore应用时间戳大于或等于的oplog条目,与–oplogReplay选项一起使用
–drop 在从转储的备份还原集合之前,从目标数据库中删除集合
–nsFrom 用于在还原操作期间配合–nsTo选项重命名命名空间。–nsFrom指定转储文件中的集合,同时–nsTo指定应在已还原数据库中使用的名称
–nsTo 用于在还原操作期间配合–nsFrom选项重命名命名空间。–nsTo指定要在还原的数据库中使用的新集合名称,同时 –nsFrom指定转储文件中的名称
–nsExclude 从还原操作中排除指定的命名空间
–nsInclude 仅包含还原操作中指定的命名空间。通过允许您指定要还原的多个集合, –nsInclude提供该–collection选项功能的超集

示例

使用–nsInclude指定恢复transactions数据库的集合,同时使用–nsExclude排除名称以_dev结尾的集合

1
mongorestore --nsInclude 'transactions.*' --nsExclude 'transactions.*_dev' dump/

例如data数据库包含以下集合:

  • Sales_customer1
  • Sales_customer2
  • Sales_customer3
  • Users_customer1
  • Users_customer2
  • Users_customer3

现在要求将data数据库下的sales_<customerName>表恢复到customer数据库的sales集合,并将users_<customerName>恢复到customer数据库的users集合

1
mongorestore --nsInclude 'data.*' --nsFrom 'data.$prefix$_$customer$' --nsTo '$customer$.$prefix$'

从压缩归档数据恢复

1
mongorestore --gzip --archive = test.20150715.gz --db test

结合Oplog进行恢复

在利用mongodump导出数据时,如果不事先锁定,dump中的集合时间点将会不一致,比如A集合10点开始备份,B集合10点半才开始备份。这时可以设置–oplog选项来同步导出dump过程中产生的oplog信息。该选项将生成一个oplog.bson的文件,该文件记录了dump过程中生成的所有oplog,以实现基于dump结束时间点的一致性备份。

插入测试数据

1
for(var i=0;i<10000;i++){db.resource.insert({a:i});};

同步进行dump备份

1
mongodump -h 10.0.139.162 --port 30000  --oplog  -o /service/mongodb/backup/

模拟删除

1
db.resource.remove({});

备份oplog

1
mongodump -h 10.0.139.162 --port 30000 -d local -c oplog.rs -o /service/mongodb/backup/oplog

恢复dump备份

1
mongorestore -h 10.0.139.162 --port 30000 --oplogReplay /service/mongodb/backup/

从oplog备份中查找故障时间点

1
2
[root@t-luhx02-v-szzb local]# bsondump oplog.rs.bson |egrep "\"op\":\"d\"\,\"ns\":\"test\.resource\"" | head -1
{"ts":{"$timestamp":{"t":1585894391,"i":1}},"t":{"$numberLong":"1"},"h":{"$numberLong":"-8046849749987056723"},"v":2,"op":"d","ns":"test.resource","ui":{"$binary":"U/2ma7QARICh+N4MDWjVdQ==","$type":"04"},"wall":{"$date":"2020-04-03T06:13:11.597Z"},"o":{"_id":{"$oid":"5e86d362d291bceb1eec05d9"}}}

恢复到故障之前

1
mongorestore -h 10.0.139.162 --port 30000 --oplogReplay --oplogLimit "1585894391:1" /service/mongodb/backup/

查询恢复数据

1
2
single:PRIMARY> db.resource.find({}).count();
10000

基于LVM快照备份

在MongoDB 3.2之前,使用WiredTiger创建MongoDB实例的卷级备份要求数据文件和日志驻留在同一卷上

在MongoDB 3.2中添加了对MongoDB实例的数据文件和日志文件不在一个卷上的卷级备份支持,但是要创建一致的备份,需要锁定数据库,停止对数据库的写入

快照发生时,数据库必须有效。这意味着数据库接受的所有写入都要完全写入磁盘,如果备份发生时写入不在磁盘,则备份不会反映这些更改。对于WiredTiger存储引擎,数据文件反映了上一个检查点的状态。检查点在每2G数据或每分钟发生一次

快照会创建整个磁盘的镜像,除非你需要备份整个系统,否则请考虑将MongoDB的数据文件、日志文件、配置文件放在专用存储设备上。

创建LVM快照

1
lvcreate --size 100M --snapshot --name mdb-snap01 /dev/vg0/mongodb

其中size并不反应磁盘上数据的总量,而是反应当前状态和创建快照之间的差异数量。应当设置足够的大小来确保数据的增长,如果快照空间不足,则快照映像将变为不可用,需要丢弃该快照重新创建

存档快照

创建快照后将快照存入单独的存储设备中,并进行压缩

1
2
umount / dev / vg0 / mdb-snap01
dd if = / dev / vg0 / mdb-snap01 | gzip> mdb-snap01.gz

恢复快照

要还原使用LVM创建的快照,请发出以下命令序列:

1
2
3
lvcreate --size 1G --name mdb-new vg0
gzip -d -c mdb-snap01.gz | dd of=/dev/vg0/mdb-new
mount /dev/vg0/mdb-new /srv/mongodb

直接从快照恢复

要在不写入压缩gz文件的情况下还原备份,请使用以下命令序列:

1
2
3
4
umount /dev/vg0/mdb-snap01
lvcreate --size 1G --name mdb-new vg0
dd if=/dev/vg0/mdb-snap01 of=/dev/vg0/mdb-new
mount /dev/vg0/mdb-new /srv/mongodb

远程备份存储

您可以使用组合流程和SSH 实施系统外备份

1
2
3
4
5
umount /dev/vg0/mdb-snap01
dd if=/dev/vg0/mdb-snap01 | ssh username@example.com gzip > /opt/backup/mdb-snap01.gz
lvcreate --size 1G --name mdb-new vg0
ssh username@example.com gzip -d -c /opt/backup/mdb-snap01.gz | dd of=/dev/vg0/mdb-new
mount /dev/vg0/mdb-new /srv/mongodb

参考链接

  1. Back Up and Restore with Filesystem Snapshots
  2. Mongodump
  3. Mongorestore
comments powered by Disqus