一、引言
前几天写了MongoDB数据库的聚合。一说到“聚合”,用过关系型数据库的人都应该知道它是一个什么东西,主要是用于对数据分类汇总和统计。大家都知道,做为DBA还有另一个重要的任务,那就是对数据库进行备份,以备当数据库发生损坏的时候,我们可以还原到以前的某个时刻,防止数据的丢失。今天我就来抛砖引玉,简单的说一说MongoDB文档数据库中的“备份-还原”的概念。二、简介 说起来数据库的“备份-还原”,在RDBMS系统中,都有很好的支持,也有很多选项可以设置,功能强大,也能自动完成大部分的备份功能,只要当初设置好了就可以了。对于MongoDB文档型的数据库来说,情况有一些不一样。在MongoDB中,要想对数据进行备份操作,需要使用脚本来执行命令完成,还原的的工作也是一样的,这是它本身支持的“备份-还原”的工作,相对RDBMS系统来说,要简单很多,不能自动完成。真的不能进行设置,来自动完成“备份和还原”的操作吗?当然可以,只是我们需要使用第三的软件才可以,而且功能越强大的,收费有的就越多,免费的也有,功能一般了,但是完成“备份-还原”的工作没问题。 接下来我们就开始说说MongoDB自己的、原生态的“备份-还原”是如何实现的,脚本很简单。mongodump命名主要完成数据的备份工作,mongorestore命令主要完成数据库的还原操作。就这两个命名,是不是很简单,那就开始我们今天的正文吧。三、数据库的备份和还原 1、MongoDB数据库的备份 1.1、mongodump命令脚本语法如下: >./mongodump -h dbhost -d dbname -o dbdirectory -h:--host【--host <hostname><:port>, -h <hostname><:port>】 MongoDB所在服务器地址,默认地址:localhost(127.0.0.1),当然也可以指定端口号:localhost:27017 -d:--db【--db <database>, -d <database>】 需要备份的数据库实例,例如:school,这个数据库是我自己建立的,所以是该备份的 -o:--out <path>【 --out <path>, -o <path>】 备份的数据存放位置,例如:./databaseBack,当然该目录需要提前建立,在备份完成后,系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据。 -u:--username <username>【--username <username>, -u <username>】 指定用于向使用认证的MongoDB数据库认证的用户名,与--password和--authenticationDatabase结合使用 -p:--password <password>【--password <password>, -p <password>】 指定用于向使用认证的MongoDB数据库认证的密码。与--username和 --authenticationDatabase选项结合使用。 -c:--collection <collection>【--collection <collection>, -c <collection>】 指定要备份的集合。如果不指定,则会将指定数据库或实例中的所有集合备份。 --port <port>: 指定MongoDB实例监听客户连接的TCP端口号。端口的默认值:27017 --gzip: MongoDB3.2或者以上的版本,可以进行压缩输出,如果mongodump指定导出到目录,则该选项会将每个文件都压缩,并添加.gz后缀;如果mongodump指定导出到文档或标准输出流,则该选项会压缩到文档或输出流中 --authenticationDatabase:【--authenticationDatabase <dbname>】 如果您未指定身份验证数据库,则mongodump会假定指定要导出的数据库保存用户的凭据。如果您未指定要导出的身份验证数据库或数据库,则mongodump假定admin数据库保存用户的凭据。 --authenticationMechanism:【 --authenticationMechanism <name>】 默认值: SCRAM-SHA-1 1.2、实例代码 1】、登陆MongoDB的客户端,查看school数据库当前的详情//登陆MongoDB的客户端 [root@linux bin]# ./mongo --host=192.168.127.130 --port=27017 MongoDB shell version v3.6.3 connecting to: mongodb://192.168.127.130:27017/ MongoDB server version: 3.6.3 Server has startup warnings: 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended. 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] //显示当前数据库列表 > show dbs admin 0.000GB config 0.000GB local 0.000GB school 0.000GB //---这个数据库就是我们要备份的 //切换到school数据库 > use school switched to db school //显示当前school数据库下有多个集合 > show tables geoInstance users //当前两个集合都有数据 > db.users.find() { "_id" : ObjectId("5b1e044733091e826f7c2c74"), "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : 100, "quantity" : 4 } { "_id" : ObjectId("5b1e044733091e826f7c2c75"), "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : 10, "quantity" : 12 } { "_id" : ObjectId("5b1e044733091e826f7c2c76"), "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : 750, "quantity" : 6 } { "_id" : ObjectId("5b1e1bfb33091e826f7c2c77"), "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : 120, "quantity" : 4 } { "_id" : ObjectId("5b1e1bfb33091e826f7c2c78"), "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "redis", "database", "NoSql" ], "likes" : 30, "quantity" : 33 } { "_id" : ObjectId("5b1e1bfb33091e826f7c2c79"), "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : 50, "quantity" : 10 } > > > db.geoInstance.find() { "_id" : ObjectId("5b1f4d21cf30d7cba03d5e03"), "loc" : [ 1, 3 ] } { "_id" : ObjectId("5b1f4d21cf30d7cba03d5e04"), "loc" : [ 3, 4 ] } { "_id" : ObjectId("5b1f4d21cf30d7cba03d5e05"), "loc" : [ 0, -3 ] } { "_id" : ObjectId("5b1f4d21cf30d7cba03d5e06"), "loc" : [ -6, 2 ] } { "_id" : ObjectId("5b1f4d21cf30d7cba03d5e07"), "loc" : { "x" : 9, "y" : 5 } } { "_id" : ObjectId("5b1f4d21cf30d7cba03d5e08"), "loc" : { "lng" : -9.2, "lat" : 21.3 } }
//退出MongoDB的客户端 > exit bye [root@linux bin]# //当前目录结构 [root@linux bin]# pwd /root/application/program/mongodb/mongodb-linux-x86_64-3.6.3/bin [root@linux bin]# databaseBack //创建保存备份文件的目录名称 //已经创建好的目录结构,databaseBack是备份目录 [root@linux bin]# ls bsondump datas logs mongod mongodump mongofiles mongoperf mongorestore mongostat databaseBack install_compass mongo mongodb.conf mongoexport mongoimport mongoreplay mongos mongotop
//代码很简单 [root@linux bin]# ./mongodump -h 192.168.127.130:27017 -d school -o ./databaseBack 2018-06-13T11:50:00.816+0800 writing school.geoInstance to 2018-06-13T11:50:00.817+0800 writing school.users to 2018-06-13T11:50:00.821+0800 done dumping school.geoInstance (6 documents) 2018-06-13T11:50:00.821+0800 done dumping school.users (6 documents) //查看备份文件 [root@linux bin]# ls ./databaseBack school [root@linux bin]# ls ./databaseBack/school geoInstance.bson geoInstance.metadata.json users.bson users.metadata.json
[root@linux bin]# ./mongodump -h 192.168.127.130:27017 --db school --collection users -o ./backCollection 2018-06-13T13:40:46.702+0800 writing school.users to 2018-06-13T13:40:46.706+0800 done dumping school.users (6 documents) [root@linux bin]# ls ./backCollection school [root@linux bin]# ls ./backCollection/school users.bson users.metadata.json [root@linux bin]#
5】、要将转储输出到存档文件,请使用--archive选项和存档文件名运行mongodump。 例如,以下操作将创建一个包含school数据库转储的文件school.20180613.archive。
[root@linux bin]# ./mongodump -h 192.168.127.130:27017 --archive=./backArchiveFile/school.2018613.archive --db school 2018-06-13T13:57:51.953+0800 writing school.geoInstance to archive './backArchiveFile/school.2018613.archive' 2018-06-13T13:57:51.955+0800 writing school.users to archive './backArchiveFile/school.2018613.archive' 2018-06-13T13:57:51.994+0800 done dumping school.geoInstance (6 documents) 2018-06-13T13:57:51.997+0800 done dumping school.users (6 documents) [root@linux bin]# ls ./backArchiveFile/ school.2018613.archive
[root@linux bin]# ./mongodump -h 192.168.127.130:27017 --db school --gzip -o ./backZip 2018-06-13T14:04:39.674+0800 writing school.geoInstance to 2018-06-13T14:04:39.675+0800 writing school.users to 2018-06-13T14:04:39.682+0800 done dumping school.geoInstance (6 documents) 2018-06-13T14:04:39.684+0800 done dumping school.users (6 documents) //显示压缩文件 [root@linux bin]# ls ./backZip/school geoInstance.bson.gz geoInstance.metadata.json.gz users.bson.gz users.metadata.json.gz
[root@linux bin]# ./mongodump -h 192.168.127.130:27017 --archive=./backZip/school.2018613.gz --db school --gzip 2018-06-13T14:08:57.311+0800 writing school.geoInstance to archive './backZip/school.2018613.gz' 2018-06-13T14:08:57.312+0800 writing school.users to archive './backZip/school.2018613.gz' 2018-06-13T14:08:57.346+0800 done dumping school.geoInstance (6 documents) 2018-06-13T14:08:57.349+0800 done dumping school.users (6 documents) [root@linux bin]# ls ./backZip/ school.2018613.gz
//登陆MongoDB客户端,显示当前数据库列表 [root@linux bin]# ./mongo --host=192.168.127.130 --port=27017 MongoDB shell version v3.6.3 connecting to: mongodb://192.168.127.130:27017/ MongoDB server version: 3.6.3 Server has startup warnings: 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended. 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] > show dbs admin 0.000GB config 0.000GB local 0.000GB school 0.000GB > //删除school数据库 > use school switched to db school > db.dropDatabase() { "dropped" : "school", "ok" : 1 } > > > show dbs admin 0.000GB config 0.000GB local 0.000GB > //退出MongoDB客户端 > exit bye [root@linux bin]#
2】、我们开始还原我们的school数据库吧,我们从集合来恢复数据库。
//还原users集合 [root@linux bin]# ./mongorestore -h 192.168.127.130:27017 --collection users --db school ./databaseBack/school/users.bson 2018-06-13T13:16:52.118+0800 checking for collection data in databaseBack/school/users.bson 2018-06-13T13:16:52.120+0800 reading metadata for school.users from databaseBack/school/users.metadata.json 2018-06-13T13:16:52.148+0800 restoring school.users from databaseBack/school/users.bson 2018-06-13T13:16:52.218+0800 no indexes to restore 2018-06-13T13:16:52.218+0800 finished restoring school.users (6 documents) 2018-06-13T13:16:52.219+0800 done //还原geoInstance集合 [root@linux bin]# ./mongorestore -h 192.168.127.130:27017 --collection geoInstance --db school ./databaseBack/school/geoInstance.bson 2018-06-13T13:18:26.353+0800 checking for collection data in databaseBack/school/geoInstance.bson 2018-06-13T13:18:26.358+0800 reading metadata for school.geoInstance from databaseBack/school/geoInstance.metadata.json 2018-06-13T13:18:26.386+0800 restoring school.geoInstance from databaseBack/school/geoInstance.bson 2018-06-13T13:18:26.456+0800 restoring indexes for collection school.geoInstance from metadata 2018-06-13T13:18:26.475+0800 finished restoring school.geoInstance (6 documents) 2018-06-13T13:18:26.475+0800 done
[root@linux bin]# ./mongo --host=192.168.127.130 --port=27017 MongoDB shell version v3.6.3 connecting to: mongodb://192.168.127.130:27017/ MongoDB server version: 3.6.3 Server has startup warnings: 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended. 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] > > > show dbs admin 0.000GB config 0.000GB local 0.000GB school 0.000GB > > > use school switched to db school > > show tables geoInstance users > > > db.users.find() { "_id" : ObjectId("5b1e044733091e826f7c2c74"), "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : 100, "quantity" : 4 } { "_id" : ObjectId("5b1e044733091e826f7c2c75"), "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : 10, "quantity" : 12 } { "_id" : ObjectId("5b1e044733091e826f7c2c76"), "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : 750, "quantity" : 6 } { "_id" : ObjectId("5b1e1bfb33091e826f7c2c77"), "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : 120, "quantity" : 4 } { "_id" : ObjectId("5b1e1bfb33091e826f7c2c78"), "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "redis", "database", "NoSql" ], "likes" : 30, "quantity" : 33 } { "_id" : ObjectId("5b1e1bfb33091e826f7c2c79"), "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : 50, "quantity" : 10 } > > > db.geoInstance.find() { "_id" : ObjectId("5b1f4d21cf30d7cba03d5e03"), "loc" : [ 1, 3 ] } { "_id" : ObjectId("5b1f4d21cf30d7cba03d5e04"), "loc" : [ 3, 4 ] } { "_id" : ObjectId("5b1f4d21cf30d7cba03d5e05"), "loc" : [ 0, -3 ] } { "_id" : ObjectId("5b1f4d21cf30d7cba03d5e06"), "loc" : [ -6, 2 ] } { "_id" : ObjectId("5b1f4d21cf30d7cba03d5e07"), "loc" : { "x" : 9, "y" : 5 } } { "_id" : ObjectId("5b1f4d21cf30d7cba03d5e08"), "loc" : { "lng" : -9.2, "lat" : 21.3 } }
4】、我们可以使用nsInclude参数来恢复指定集合的数据。
[root@linux bin]# ./mongorestore -h 192.168.127.130:27017 --nsInclude school.users ./databaseBack/ 2018-06-13T14:19:59.942+0800 preparing collections to restore from 2018-06-13T14:19:59.946+0800 reading metadata for school.users from databaseBack/school/users.metadata.json 2018-06-13T14:19:59.970+0800 restoring school.users from databaseBack/school/users.bson 2018-06-13T14:19:59.977+0800 no indexes to restore 2018-06-13T14:19:59.977+0800 finished restoring school.users (6 documents) 2018-06-13T14:19:59.977+0800 done //这是在有数据的情况下执行恢复 [root@linux bin]# ./mongorestore -h 192.168.127.130:27017 --nsInclude school.users ./databaseBack/ 2018-06-13T14:21:10.743+0800 preparing collections to restore from 2018-06-13T14:21:10.747+0800 reading metadata for school.users from databaseBack/school/users.metadata.json 2018-06-13T14:21:10.748+0800 restoring school.users from databaseBack/school/users.bson 2018-06-13T14:21:10.755+0800 error: multiple errors in bulk operation: - E11000 duplicate key error collection: school.users index: _id_ dup key: { : ObjectId('5b1e044733091e826f7c2c74') } - E11000 duplicate key error collection: school.users index: _id_ dup key: { : ObjectId('5b1e044733091e826f7c2c75') } - E11000 duplicate key error collection: school.users index: _id_ dup key: { : ObjectId('5b1e044733091e826f7c2c76') } - E11000 duplicate key error collection: school.users index: _id_ dup key: { : ObjectId('5b1e1bfb33091e826f7c2c77') } - E11000 duplicate key error collection: school.users index: _id_ dup key: { : ObjectId('5b1e1bfb33091e826f7c2c78') } - E11000 duplicate key error collection: school.users index: _id_ dup key: { : ObjectId('5b1e1bfb33091e826f7c2c79') } 2018-06-13T14:21:10.755+0800 no indexes to restore 2018-06-13T14:21:10.755+0800 finished restoring school.users (6 documents) 2018-06-13T14:21:10.755+0800 done
5】、我们可以使用zip压缩文件,通过archive参数来恢复指定数据库的数据。
[root@linux bin]# ./mongorestore -h 192.168.127.130:27017 --gzip --db school --archive=./backZip/school.2018613.gz 2018-06-13T14:26:48.939+0800 the --db and --collection args should only be used when restoring from a BSON file. Other uses are deprecated and will not exist in the future; use --nsInclude instead 2018-06-13T14:26:49.591+0800 preparing collections to restore from 2018-06-13T14:26:50.041+0800 reading metadata for school.geoInstance from archive './backZip/school.2018613.gz' 2018-06-13T14:26:50.071+0800 restoring school.geoInstance from archive './backZip/school.2018613.gz' 2018-06-13T14:26:51.132+0800 restoring indexes for collection school.geoInstance from metadata 2018-06-13T14:26:51.150+0800 finished restoring school.geoInstance (6 documents) 2018-06-13T14:26:51.152+0800 reading metadata for school.users from archive './backZip/school.2018613.gz' 2018-06-13T14:26:51.181+0800 restoring school.users from archive './backZip/school.2018613.gz' 2018-06-13T14:26:51.837+0800 no indexes to restore 2018-06-13T14:26:51.838+0800 finished restoring school.users (6 documents) 2018-06-13T14:26:51.838+0800 done //以前已经删除了school数据库 [root@linux bin]# ./mongo --host 192.168.127.130 --port=27017 MongoDB shell version v3.6.3 connecting to: mongodb://192.168.127.130:27017/ MongoDB server version: 3.6.3 Server has startup warnings: 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended. 2018-06-13T11:27:09.721+0800 I CONTROL [initandlisten] 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2018-06-13T11:27:09.723+0800 I CONTROL [initandlisten] > show dbs admin 0.000GB config 0.000GB local 0.000GB school 0.000GB //数据库已经存在了,说明恢复成功