首页 > 代码库 > 第三部分 管理篇 第八章 MongoDB服务管理

第三部分 管理篇 第八章 MongoDB服务管理

1、数据导出 mongoexport

在日常的数据库管理中经常会遇到导入导出数据的需求,下面就介绍实用工具mongoexport和mongoimport的使用方法,假设库里有一张user表,里面有2条记录,我们将到导出。

> db.user.insert({username:"Jerry",age:100});
WriteResult({ "nInserted" : 1 })
> db.user.insert({username:"Tom",age:20});
WriteResult({ "nInserted" : 1 })
> db.user.find();
{ "_id" : ObjectId("54a8e0d5811433efe7a7d1a3"), "username" : "Jerry", "age" : 100 }
{ "_id" : ObjectId("54a8e0de811433efe7a7d1a4"), "username" : "Tom", "age" : 20 }
导出数据

[root@localhost bin]# ./mongoexport -d test -c user -o user.dat
connected to: 127.0.0.1
exported 2 records

参数说明:

  • -d指明使用的库,本例中为test
  • -c指明要导出的表,本例中为user
  • -o指明要导出的文件名,本例中为user.dat
从上面可以看到导出的方式使用的是JSON的样式。
验证是否导出:
[root@localhost bin]# ll
total 283572
-rwxr-xr-x. 1 mongodb mongodb 23603184 Dec  9 07:38 bsondump
-rwxr-xr-x. 1 mongodb mongodb 11900240 Dec  9 07:38 mongo
-rwxr-xr-x. 1 mongodb mongodb 23773296 Dec  9 07:38 mongod
-rwxr-xr-x. 1 mongodb mongodb 23676016 Dec  9 07:38 mongodump
-rwxr-xr-x. 1 mongodb mongodb 23619312 Dec  9 07:38 mongoexport
-rwxr-xr-x. 1 mongodb mongodb 23667776 Dec  9 07:38 mongofiles
-rwxr-xr-x. 1 mongodb mongodb 23644016 Dec  9 07:38 mongoimport
-rwxr-xr-x. 1 mongodb mongodb 23614480 Dec  9 07:38 mongooplog
-rwxr-xr-x. 1 mongodb mongodb 23424896 Dec  9 07:38 mongoperf
-rwxr-xr-x. 1 mongodb mongodb 23713104 Dec  9 07:38 mongorestore
-rwxr-xr-x. 1 mongodb mongodb 18433232 Dec  9 07:38 mongos
-rwxr-xr-x. 1 mongodb mongodb 23663984 Dec  9 07:38 mongostat
-rwxr-xr-x. 1 mongodb mongodb 23607088 Dec  9 07:38 mongotop
-rw-r--r--. 1 root    root         171 Jan  4 14:43 user.dat
1.1、导出CSV格式的文件
[root@localhost bin]# ./mongoexport -d test -c user --csv -f username,age -o user_cvs.dat
connected to: 127.0.0.1
exported 2 records
参数说明:
  • -csv:只要导出为csv格式
  • -f指明需要导出哪些例

2、数据导入mongoimport
在上面的例子中的是导出工具的使用,那么本节将讨论如何向表中导入数据。
2.1、导入JSON数据
先将表user删除,以便演示效果。
[root@localhost bin]# ./mongo
MongoDB shell version: 2.6.6
connecting to: test
> db.user.drop();
true
确认没有该表
> show collections
c1
c2
c3
c4
fs.chunks
fs.files
students
students_res
system.indexes
system.js
导入数据:
[root@localhost bin]# ./mongoimport -d test -c user user.dat
connected to: 127.0.0.1
2015-01-04T14:50:32.595+0800 imported 2 objects
验证是否导入成功:
[root@localhost bin]# ./mongo
MongoDB shell version: 2.6.6
connecting to: test
> db.user.find();
{ "_id" : ObjectId("54a8e0d5811433efe7a7d1a3"), "username" : "Jerry", "age" : 100 }
{ "_id" : ObjectId("54a8e0de811433efe7a7d1a4"), "username" : "Tom", "age" : 20 }
说明:导入数据的时候会隐式创建表结构。

2.2、导入csv数据
先将user表删除掉,以便演示效果。
> db.user.drop();
true
> show collections
c1
c2
c3
c4
fs.chunks
fs.files
students
students_res
system.indexes
system.js
然后导入数据:
[root@localhost bin]# ./mongoimport -d test -c user --type csv -headerline --file user_cvs.dat
connected to: 127.0.0.1
2015-01-04T14:53:14.316+0800 imported 2 objects
[root@localhost bin]# ./mongo
MongoDB shell version: 2.6.6
connecting to: test
> db.user.find();
{ "_id" : ObjectId("54a8e35adeaed25af579df60"), "username" : "Jerry", "age" : 100 }
{ "_id" : ObjectId("54a8e35adeaed25af579df61"), "username" : "Tom", "age" : 20 }
参数说明:
  • -type:指明要导入的文件格式
  • -headerline:指明不导入第一行,因为第一行是列明
  • -file:指明要导入的文件路径。
注意:csv格式良好,主流数据库都支持导出为csv的格式,所以这种格式非常利于异构数据迁移。

3、数据备份mongodump
可以用mongodump来做MongoDB的库或者表级别的备份,下面举例说明:
备份test数据库:
[root@localhost bin]# ./mongodump -d test
connected to: 127.0.0.1
2015-01-04T14:56:07.845+0800 DATABASE: test      to     dump/test
2015-01-04T14:56:07.847+0800    test.system.indexes to dump/test/system.indexes.bson
2015-01-04T14:56:07.877+0800             13 documents
2015-01-04T14:56:07.877+0800    test.xuz to dump/test/xuz.bson
2015-01-04T14:56:07.884+0800             64 documents
2015-01-04T14:56:07.884+0800    Metadata for test.xuz to dump/test/xuz.metadata.json
2015-01-04T14:56:07.885+0800    test.c1 to dump/test/c1.bson
2015-01-04T14:56:07.926+0800             4 documents
2015-01-04T14:56:07.926+0800    Metadata for test.c1 to dump/test/c1.metadata.json
2015-01-04T14:56:07.927+0800    test.c2 to dump/test/c2.bson
2015-01-04T14:56:07.928+0800             3 documents
2015-01-04T14:56:07.929+0800    Metadata for test.c2 to dump/test/c2.metadata.json
2015-01-04T14:56:07.929+0800    test.c3 to dump/test/c3.bson
2015-01-04T14:56:07.938+0800             4 documents
2015-01-04T14:56:07.938+0800    Metadata for test.c3 to dump/test/c3.metadata.json
2015-01-04T14:56:07.939+0800    test.c4 to dump/test/c4.bson
2015-01-04T14:56:07.941+0800             3 documents
2015-01-04T14:56:07.941+0800    Metadata for test.c4 to dump/test/c4.metadata.json
2015-01-04T14:56:07.942+0800    test.system.js to dump/test/system.js.bson
2015-01-04T14:56:07.951+0800             2 documents
2015-01-04T14:56:07.952+0800    Metadata for test.system.js to dump/test/system.js.metadata.json
2015-01-04T14:56:07.952+0800    test.fs.files to dump/test/fs.files.bson
2015-01-04T14:56:07.954+0800             1 documents
2015-01-04T14:56:07.954+0800    Metadata for test.fs.files to dump/test/fs.files.metadata.json
2015-01-04T14:56:07.954+0800    test.fs.chunks to dump/test/fs.chunks.bson
2015-01-04T14:56:07.972+0800             1 documents
2015-01-04T14:56:07.973+0800    Metadata for test.fs.chunks to dump/test/fs.chunks.metadata.json
2015-01-04T14:56:07.974+0800    test.students to dump/test/students.bson
2015-01-04T14:56:07.983+0800             8 documents
2015-01-04T14:56:07.983+0800    Metadata for test.students to dump/test/students.metadata.json
2015-01-04T14:56:07.983+0800    test.students_res to dump/test/students_res.bson
2015-01-04T14:56:07.985+0800             1 documents
2015-01-04T14:56:07.985+0800    Metadata for test.students_res to dump/test/students_res.metadata.json
2015-01-04T14:56:07.985+0800    test.user to dump/test/user.bson
2015-01-04T14:56:07.987+0800             2 documents
2015-01-04T14:56:07.987+0800    Metadata for test.user to dump/test/user.metadata.json
此时会在当前目录下创建一个dump目录,里面存放备份出来的文件,也可以指定备份存放的目录。
[root@localhost bin]# ll
total 283580
-rwxr-xr-x. 1 mongodb mongodb 23603184 Dec  9 07:38 bsondump
drwxr-xr-x. 3 root    root        4096 Jan  4 14:56 dump
-rwxr-xr-x. 1 mongodb mongodb 11900240 Dec  9 07:38 mongo
-rwxr-xr-x. 1 mongodb mongodb 23773296 Dec  9 07:38 mongod
-rwxr-xr-x. 1 mongodb mongodb 23676016 Dec  9 07:38 mongodump
-rwxr-xr-x. 1 mongodb mongodb 23619312 Dec  9 07:38 mongoexport
-rwxr-xr-x. 1 mongodb mongodb 23667776 Dec  9 07:38 mongofiles
-rwxr-xr-x. 1 mongodb mongodb 23644016 Dec  9 07:38 mongoimport
-rwxr-xr-x. 1 mongodb mongodb 23614480 Dec  9 07:38 mongooplog
-rwxr-xr-x. 1 mongodb mongodb 23424896 Dec  9 07:38 mongoperf
-rwxr-xr-x. 1 mongodb mongodb 23713104 Dec  9 07:38 mongorestore
-rwxr-xr-x. 1 mongodb mongodb 18433232 Dec  9 07:38 mongos
-rwxr-xr-x. 1 mongodb mongodb 23663984 Dec  9 07:38 mongostat
-rwxr-xr-x. 1 mongodb mongodb 23607088 Dec  9 07:38 mongotop
-rw-r--r--. 1 root    root          38 Jan  4 14:47 user_cvs.dat
-rw-r--r--. 1 root    root         171 Jan  4 14:43 user.dat
指定备份存放的目录:
[root@localhost bin]# ./mongodump -d local -o /usr/local/xuz
connected to: 127.0.0.1
2015-01-04T14:58:19.249+0800 DATABASE: local     to     /usr/local/xuz/local
2015-01-04T14:58:19.269+0800    local.system.indexes to /usr/local/xuz/local/system.indexes.bson
2015-01-04T14:58:19.278+0800             1 documents
2015-01-04T14:58:19.278+0800    local.startup_log to /usr/local/xuz/local/startup_log.bson
2015-01-04T14:58:19.283+0800             2 documents
2015-01-04T14:58:19.283+0800    Metadata for local.startup_log to /usr/local/xuz/local/startup_log.metadata.json
此时将备份文件存放到了/usr/local/xuz目录下了。

4、数据库恢复mongorestore
由于刚刚已经做了备份,所以我们先将库test删除掉。
[root@localhost bin]# ./mongo
MongoDB shell version: 2.6.6
connecting to: test
> show dbs
admin  (empty)
local  0.078GB
test   0.078GB
> use test
switched to db test
> db.dropDatabase();
{ "dropped" : "test", "ok" : 1 }
> show dbs
admin  (empty)
local  0.078GB

接下来我们进行数据库的恢复
[root@localhost bin]# ./mongorestore -d test dump/*
connected to: 127.0.0.1
2015-01-04T15:00:48.848+0800 dump/test/system.js.bson
2015-01-04T15:00:48.848+0800    going into namespace [test.system.js]
2 objects found
2015-01-04T15:00:48.857+0800    Creating index: { key: { _id: 1 }, name: "_id_", ns: "test.system.js" }
2015-01-04T15:00:53.133+0800 dump/test/students_res.bson
2015-01-04T15:00:53.133+0800    going into namespace [test.students_res]
1 objects found
2015-01-04T15:00:53.142+0800    Creating index: { key: { _id: 1 }, name: "_id_", ns: "test.students_res" }
2015-01-04T15:00:53.142+0800 dump/test/user.bson
2015-01-04T15:00:53.143+0800    going into namespace [test.user]
2 objects found
2015-01-04T15:00:53.145+0800    Creating index: { key: { _id: 1 }, name: "_id_", ns: "test.user" }
2015-01-04T15:00:53.153+0800 dump/test/c4.bson
2015-01-04T15:00:53.153+0800    going into namespace [test.c4]
3 objects found
2015-01-04T15:00:53.154+0800    Creating index: { key: { _id: 1 }, name: "_id_", ns: "test.c4" }
2015-01-04T15:00:53.222+0800 dump/test/students.bson
2015-01-04T15:00:53.222+0800    going into namespace [test.students]
8 objects found
2015-01-04T15:00:53.224+0800    Creating index: { key: { _id: 1 }, name: "_id_", ns: "test.students" }
2015-01-04T15:00:53.254+0800 dump/test/xuz.bson
2015-01-04T15:00:53.254+0800    going into namespace [test.xuz]
64 objects found
2015-01-04T15:00:53.255+0800    Creating index: { key: { _id: 1 }, name: "_id_", ns: "test.xuz" }
2015-01-04T15:00:53.282+0800 dump/test/fs.chunks.bson
2015-01-04T15:00:53.282+0800    going into namespace [test.fs.chunks]
1 objects found
2015-01-04T15:00:53.282+0800    Creating index: { key: { _id: 1 }, name: "_id_", ns: "test.fs.chunks" }
2015-01-04T15:00:53.298+0800    Creating index: { unique: true, key: { files_id: 1, n: 1 }, name: "files_id_1_n_1", ns: "test.fs.chunks" }
2015-01-04T15:00:53.356+0800 dump/test/c1.bson
2015-01-04T15:00:53.356+0800    going into namespace [test.c1]
4 objects found
2015-01-04T15:00:53.356+0800    Creating index: { key: { _id: 1 }, name: "_id_", ns: "test.c1" }
2015-01-04T15:00:53.375+0800 dump/test/fs.files.bson
2015-01-04T15:00:53.376+0800    going into namespace [test.fs.files]
1 objects found
2015-01-04T15:00:53.376+0800    Creating index: { key: { _id: 1 }, name: "_id_", ns: "test.fs.files" }
2015-01-04T15:00:53.386+0800    Creating index: { key: { filename: 1 }, name: "filename_1", ns: "test.fs.files" }
2015-01-04T15:00:53.390+0800 dump/test/c2.bson
2015-01-04T15:00:53.390+0800    going into namespace [test.c2]
3 objects found
2015-01-04T15:00:53.392+0800    Creating index: { key: { _id: 1 }, name: "_id_", ns: "test.c2" }
2015-01-04T15:00:53.396+0800 dump/test/c3.bson
2015-01-04T15:00:53.397+0800    going into namespace [test.c3]
4 objects found
2015-01-04T15:00:53.397+0800    Creating index: { key: { _id: 1 }, name: "_id_", ns: "test.c3" }
验证数据库
[root@localhost bin]# ./mongo
MongoDB shell version: 2.6.6
connecting to: test
> show dbs
admin  (empty)
local  0.078GB
test   0.078GB
> use test
switched to db test
> show collections
c1
c2
c3
c4
fs.chunks
fs.files
students
students_res
system.indexes
system.js
user
xuz
此时数据库又回来了,其实要想恢复数据库大可不必先删除test库,只要指明-drop参数,就可以在恢复的时候先删除表然后再向表中插入数据。

5、访问控制
官方手册中启动MongoDB服务时没有任何参数,一旦客户端连接后可以对数据库任意操作,而且可以远程访问数据库,所以推荐开发阶段可以不设置任何参数,但对于生产环境还是要仔细考虑一下安全方面的因素,而提高MongoBD数据库安全有几个方面:
  • 绑定IP内网地址访问MongoDB服务。
  • 设置监听端口
  • 使用用户名和口令登录。
5.1、绑定IP内网地址访问MongoDB服务
MongoDB可以限制只允许某一特定的IP来访问,只要在启动时加上一个参数bind_ip即可,如下:
服务端限制只有192.168.134.21这个IP可以访问MongoDB服务。
[root@localhost bin]# ./mongod --dbpath=/var/mongodb/data/ --logpath=/var/mongodb/logs/log.log -fork --bind_ip 192.168.134.21
about to fork child process, waiting until server is ready for connections.
forked process: 29111
child process started successfully, parent exiting
此时客户端访问时需要明确指定服务端的IP,否则会报错。
[root@localhost bin]# ./mongo
MongoDB shell version: 2.6.6
connecting to: test
2015-01-04T15:07:40.277+0800 warning: Failed to connect to 127.0.0.1:27017, reason: errno:111 Connection refused
2015-01-04T15:07:40.278+0800 Error: couldn‘t connect to server 127.0.0.1:27017 (127.0.0.1), connection attempt failed at src/mongo/shell/mongo.js:146
exception: connect failed
[root@localhost bin]# ./mongo 192.168.134.21
MongoDB shell version: 2.6.6
connecting to: 192.168.134.21/test


5.2、设置监听端口
官方默认的监听端口是27017,为了安全起见,一般都会修改这个监听端口,避免恶意的连接尝试,具体如下:
将服务端监听端口修改为28018
[root@localhost bin]# ./mongod --dbpath=/var/mongodb/data/ --logpath=/var/mongodb/logs/log.log -fork --port 28018
about to fork child process, waiting until server is ready for connections.
forked process: 29148
child process started successfully, parent exiting
[root@localhost bin]# 
客户端访问时不指定端口,会连接到默认的端口27017,此时就会报错。
[root@localhost bin]# ./mongo
MongoDB shell version: 2.6.6
connecting to: test
2015-01-04T15:10:54.507+0800 warning: Failed to connect to 127.0.0.1:27017, reason: errno:111 Connection refused
2015-01-04T15:10:54.508+0800 Error: couldn‘t connect to server 127.0.0.1:27017 (127.0.0.1), connection attempt failed at src/mongo/shell/mongo.js:146
exception: connect failed
所以当服务端指定了端口后,客户端必须要明确指定端口才可以正常访问。
[root@localhost bin]# ./mongo --port 28018
MongoDB shell version: 2.6.6
connecting to: 127.0.0.1:28018/test


5.3、使用用户名和口令登录
MongoDB默认的启动时不验证用户明和密码的,启动MongoDB后,可以直接用MongoDB连接上来,对所有的库具有root权限,所以启动的时候指定参数,可以阻止客户端的访问和连接。
先启用系统的登录验证模块,只需要在启动时指定auth参数即可,如:
[root@localhost bin]# ./mongod --dbpath=/var/mongodb/data/ --logpath=/var/mongodb/logs/log.log -fork--auth
about to fork child process, waiting until server is ready for connections.
forked process: 29200
child process started successfully, parent exiting
本地客户端连接:
[root@localhost bin]# ./mongo
MongoDB shell version: 2.6.6
connecting to: test

为什么我们启用了登录验证模块,但是我们登录时没有指定用户,还可以登录呢?在最初始化的时候MongoDB都会默认有一个admin数据库(默认是空的),而admin.system.users中将会保存比在其他数据库中设置的用户权限更大的用户信息。
注意:当admin.system.users中没有添加任何用户时,即时MongoDB启动时添加了--auth参数,如果在除admin数据库中添加了用户,此时不进行任何认证依然可以使用任何操作,直到你在admin.system.users中添加了一个用户。

建立系统root用户
在admin库中添加一个用户root
> use admin
switched to db admin
> db.addUser("root","111");
WARNING: The ‘addUser‘ shell helper is DEPRECATED. Please use ‘createUser‘ instead
Successfully added user: { "user" : "root", "roles" : [ "root" ] }
> db.auth("root","111");
1

本地客户端连接,但是不指定用户,结果如下:
[root@localhost bin]# ./mongo
MongoDB shell version: 2.6.6
connecting to: test
> show collections
2015-01-04T15:20:37.551+0800 error: {
        "$err" : "not authorized for query on test.system.namespaces",
        "code" : 13
} at src/mongo/shell/query.js:131

连接test库,但是要进一步操作时提示了异常,看来MongoDB允许未授权连接,不能进行任何本地客户端连接,指定用户,结果如下:
[root@localhost bin]# ./mongo -u root -p
MongoDB shell version: 2.6.6
Enter password:
connecting to: test
> use admin
switched to db admin
> show collections
system.indexes
system.users
system.version

建立指定权限用户
MongoDB也支持为某个特定的数据库来设置用户,如我们为test库设置一个只读用户user_reader
> db.addUser("user_header","user_pwd",true)
WARNING: The ‘addUser‘ shell helper is DEPRECATED. Please use ‘createUser‘ instead
Successfully added user: { "user" : "user_header", "roles" : [ "read" ] }
此时该用户对test库只有只读权限。
-----------------------MongoDB系列文章更新--------------------------------------------

第一部分 基础篇 第一章 走进MongoDB

第一部分 基础篇 第二章 安装MongoDB

第一部分 基础篇 第三章 MongoDB体系结构

第一部分 基础篇 第四章 MongoDB快速入门

第一部分 基础篇 第四章 MongoDB查询

第二部分 应用篇 第五章 MongoDB高级查询

第二部分 应用篇 第六章 MongoDB GridFS

第二部分 应用篇 第七章 MongoDB MapReduce

第三部分 管理篇 第八章 MongoDB服务管理