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 }
导出数据
[[email protected] 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的样式。
验证是否导出:
[[email protected] 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格式的文件
[[email protected] 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删除,以便演示效果。
[[email protected] 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
导入数据:
[[email protected] bin]# ./mongoimport -d test -c user user.dat
connected to: 127.0.0.1
2015-01-04T14:50:32.595+0800 imported 2 objects
验证是否导入成功:
[[email protected] 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
然后导入数据:
[[email protected] 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
[[email protected] 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数据库:
[[email protected] 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目录,里面存放备份出来的文件,也可以指定备份存放的目录。
[[email protected] 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
指定备份存放的目录:
[[email protected] 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删除掉。
[[email protected] 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
>
接下来我们进行数据库的恢复
[[email protected] 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" }
验证数据库
[[email protected] 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服务。
[[email protected] 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,否则会报错。
[[email protected] 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
[[email protected] bin]# ./mongo 192.168.134.21
MongoDB shell version: 2.6.6
connecting to: 192.168.134.21/test
>
5.2、设置监听端口
官方默认的监听端口是27017,为了安全起见,一般都会修改这个监听端口,避免恶意的连接尝试,具体如下:
将服务端监听端口修改为28018
[[email protected] 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
[[email protected] bin]#
客户端访问时不指定端口,会连接到默认的端口27017,此时就会报错。
[[email protected] 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
所以当服务端指定了端口后,客户端必须要明确指定端口才可以正常访问。
[[email protected] 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参数即可,如:
[[email protected] 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
本地客户端连接:
[[email protected] 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
>
本地客户端连接,但是不指定用户,结果如下:
[[email protected] 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允许未授权连接,不能进行任何本地客户端连接,指定用户,结果如下:
[[email protected] 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 MapReduce