`
jorwen_fang
  • 浏览: 50691 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

MongoDB学习笔记(八):管理

阅读更多

1.启动停止 & 运行监控 

【启动MongoDB】 

执行mongod命令,启动mongod进程,就会启动MongoDB数据库服务。我们在命令行窗口中运行mongod --help可以看到这个命令有大量可选的option,我们这里重点介绍几个: 

1》 --dbpath:指定数据目录,每一个mongod进程都要有一个独立的数据目录,如果不指定这个选项,默认的数据目录是/data/db/(Windows下是C:\data\db\)。当mongod启动后,会在数据目录中创建mongod.lock文件,这个文件可以防止别的mongod进程再次使用这个目录作为数据目录。 

2》 --port:指定数据库服务监听端口号,默认为27017,如果同一台服务器要启动多个mongod进程,这些进程要分别指定不同端口。 

3》 --fork:以守护进程的形式运行MongoDB,Windows平台不支持这个参数,Linux和Unix平台支持! 

4》 --logpath:指定日志输出路径 

5》 --config:指定配置文件,通过该配置文件配置上述各类信息。

1.E:\mongodb\mongodb-win32-x86_64-2.0.6\bin>mongod --dbpath E:\mongoddata --port 27777 --logpath E:\mongodlog\log1.log
2.all output going to: E:\mongodlog\log1.log

上面我们启动了一个指定数据目录、日志输出目录并且监听端口在27777上的mongod服务!我们再通过配置文件的形式启动一个,配置文件的内容是:

01.#mongod启动配置文件
02. 
03.port = 27777 #指定端口
04. 
05.dbpath = E:\mongoddata #指定数据目录
06. 
07.logpath = E:\mongodlog\log1.log #指定日志输出目录
08. 
09.# 对于如--fork这类的开关选项,在配置文件中使用要指定值为true,fork = true
1.E:\mongodb\mongodb-win32-x86_64-2.0.6\bin>mongod --config E:\config.conf
2.all output going to: E:\mongodlog\log1.log

上述即通过配置文件启动了mongod服务。我们前面也介绍了,Windows平台中,通过--install选项,还可以将mongod以服务的形式进行安装,这里就不在演示了。 

【停止MongoDB】 

Windows平台上,如果mongod服务是作为前台进程运行在服务器上(即cmd窗口的形式),可以直接ctrl + c的方式结束,如果mongod是以服务的形式运行,可以到“服务”管理窗口进行结束,或在命令行中,通过net stop mongodb来结束服务(通过net start mongodb来启动服务)。Linux/Unix平台,则通过kill命令来关闭服务。 

--注意:MongoDB权威指南还提到了在admin数据库下,通过运行shutdown({"shutdown" : 1})命令的方式,或在shell中调用其包装函数db.shutdownServer()的形式停止服务,经试验,这种方式在Windows平台上,在关闭掉服务后,都会再次重启服务,不会将服务完全停止掉! 

【运行监控】 

默认情况下,启动mongod服务的同时,会启动一个非常基本的http服务器,该服务器监听的端口总是mongod服务监听端口+1000, 通过浏览器可以访问这个http服务,这里会列举出当前mongod服务的一些运行信息。 

除了上述这种方式外,shell中通过运行serverStatus命令同样可以查看mongod的运行信息:

01.> db.runCommand({"serverStatus" : 1})
02.{
03."host" : "liuxj-PC",
04."version" : "2.0.6",
05."process" : "mongod",
06."uptime" : 1012,
07."uptimeEstimate" : 674,
08."localTime" : ISODate("2012-08-25T07:08:07.120Z"),
09."globalLock" : {
10."totalTime" : 1011540200,
11."lockTime" : 0,
12."ratio" : 0,
13."currentQueue" : {
14."total" : 0,
15."readers" : 0,
16."writers" : 0
17.},
18."activeClients" : {
19."total" : 0,
20."readers" : 0,
21."writers" : 0
22.}
23.},
24."mem" : {
25."bits" : 64,
26."resident" : 20,
27."virtual" : 61,
28."supported" : true,
29."mapped" : 0,
30."mappedWithJournal" : 0
31.},
32."connections" : {
33."current" : 1,
34."available" : 19999
35.},
36."extra_info" : {
37."note" : "fields vary by platform",
38."page_faults" : 5381,
39."usagePageFileMB" : 20,
40."totalPageFileMB" : 4094,
41."availPageFileMB" : 2603,
42."ramMB" : 2047
43.},
44."indexCounters" : {
45."note" : "not supported on this platform"
46.},
47."backgroundFlushing" : {
48."flushes" : 16,
49."total_ms" : 0,
50."average_ms" : 0,
51."last_ms" : 0,
52."last_finished" : ISODate("2012-08-25T07:07:15.749Z")
53.},
54."cursors" : {
55."totalOpen" : 0,
56."clientCursors_size" : 0,
57."timedOut" : 0
58.},
59."network" : {
60."bytesIn" : 157,
61."bytesOut" : 186,
62."numRequests" : 2
63.},
64."opcounters" : {
65."insert" : 0,
66."query" : 1,
67."update" : 0,
68."delete" : 0,
69."getmore" : 0,
70."command" : 3
71.},
72."asserts" : {
73."regular" : 0,
74."warning" : 0,
75."msg" : 0,
76."user" : 0,
77."rollovers" : 0
78.},
79."writeBacksQueued" : false,
80."dur" : {
81."commits" : 22,
82."journaledMB" : 0,
83."writeToDataFilesMB" : 0,
84."compression" : 0,
85."commitsInWriteLock" : 0,
86."earlyCommits" : 0,
87."timeMs" : {
88."dt" : 3104,
89."prepLogBuffer" : 0,
90."writeToJournal" : 0,
91."writeToDataFiles" : 0,
92."remapPrivateView" : 0
93.}
94.},
95."ok" : 1
96.}
97.>

上面返回的文档,就是当前服务器的相关运行信息,基本上都是顾名思义的,我们解释其中几个,"globalLock"表示了全局写入锁占用服务器多少时间(微妙),“mem”代表了服务器内存映射了多少数据,服务器进程的常驻内存和虚拟内存的占用情况(MB),“backgroundFlushing”表示后台做了多少次fsync(后面后讲到)及用了多少时间,“opcounters”表示各种操作执行的次数,“asserts”:统计了断言的次数。这些统计信息从mongod服务起来后就开始进行,如果数字超过一定范围,就会复位,一旦某个计数器复位,所有计数器同时复位,asserts中的rollovers键对应的值会加1。 

上面提到的两种监控方式给出的都是静态信息,MongoDB还给出了一个工具 mongostat(bin目录中),这个工具动态给出当前数据库服务的相关信息,每秒钟刷新一次,以列表的形式展现:

01.insert  query update delete getmore command flushes mapped  vsize    res faults locked % idx miss %     qr|qw   ar|aw  netIn netOut  conn       time
02.0      0      0      0       0       1       0     0m    62m    20m      0        0          0       0|0     0|0    62b     1k     2   15:20:36
03.0      0      0      0       0       1       0     0m    62m    20m      0        0          0       0|0     0|0    62b     1k     2   15:20:37
04.0      0      0      0       0       1       0     0m    62m    20m      0        0          0       0|0     0|0    62b     1k     2   15:20:38
05.0      0      0      0       0       1       0     0m    62m    20m      0        0          0       0|0     0|0    62b     1k     2   15:20:39
06.0      0      0      0       0       1       0     0m    62m    20m      0        0          0       0|0     0|0    62b     1k     2   15:20:40
07.0      0      0      0       0       1       0     0m    62m    20m      0        0          0       0|0     0|0    62b     1k     2   15:20:41
08.0      0      0      0       0       1       0     0m    62m    20m      0        0          0       0|0     0|0    62b     1k     2   15:20:42
09.0      0      0      0       0       1       0     0m    62m    20m      0        0          0       0|0     0|0    62b     1k     2   15:20:43
10.0      0      0      0       0       1       0     0m    62m    20m      0        0          0       0|0     0|0    62b     1k     2   15:20:44
11.0      0      0      0       0       1       0     0m    62m    20m      0        0          0       0|0     0|0    62b     1k     2   15:20:45
12.insert  query update delete getmore command flushes mapped  vsize    res faults locked % idx miss %     qr|qw   ar|aw  netIn netOut  conn       time
13.0      0      0      0       0       1       0     0m    62m    20m      0        0          0       0|0     0|0    62b     1k     2   15:20:46
14.0      0      0      0       0       1       0     0m    62m    20m      0        0          0       0|0     0|0    62b     1k     2   15:20:47
15.0      0      0      0       0       1       0     0m    62m    20m      0        0          0       0|0     0|0    62b     1k     2   15:20:48
16.0      0      0      0       0       1       0     0m    62m    20m      0        0          0       0|0     0|0    62b     1k     2   15:20:49

现在除了MongoDB本身提供的多种监控方式外,还有很多第三方插件可以做这个事情(通过执行serverStatus命令或访问http://ip:port/_status来获取数据,并给出各种易用的展示),如Nagios, Munin, Ganglia, Cacti。最后给大家一个网址:http://www.mongodb.org/display/DOCS/Monitoring+and+Diagnostics 这里可以查看监控相关的文档和工具。

 

2.安全认证 

系统管理员的一个重要工作就是确保系统的安全,使MongoDB安全的最好的方式就是在一个可信的环境中运行服务,保证只有可信的机器才能访问它。MongoDB支持对单个连接的认证。 

启动MongoDB时,通过使用--auth选项,就可以开启数据库的安全性检查,此时只有经过数据库认证的用户才可以进行读写操作。我们首先要在未开启安全性检查的情况下(不使用--auth选项)向数据库中添加用户:

01.> use mylearndb;
02.switched to db mylearndb
03.> db
04.mylearndb
05.> db.addUser("jimmy", "1");
06.{ "n" : 0, "connectionId" : 1, "err" : null, "ok" : 1 }
07.{
08."user" : "jimmy",
09."readOnly" : false,
10."pwd" : "265134bf5a25fa7d91d60fba1555ba3b",
11."_id" : ObjectId("50398ec4fe9dca5a555cab3d")
12.}
13.> use mytestdb;
14.switched to db mytestdb
15.> db
16.mytestdb
17.> db.addUser("tom", "1");
18.{ "n" : 0, "connectionId" : 1, "err" : null, "ok" : 1 }
19.{
20."user" : "tom",
21."readOnly" : false,
22."pwd" : "95ac6a199add474e22797396497bfa77",
23."_id" : ObjectId("50398ee4fe9dca5a555cab3e")
24.}
25.> use admin;
26.switched to db admin
27.> db
28.admin
29.> db.addUser("Green", "1");
30.{ "n" : 0, "connectionId" : 1, "err" : null, "ok" : 1 }
31.{
32."user" : "Green",
33."readOnly" : false,
34."pwd" : "10eadce7fd2701b042e05e1c3f066d5b",
35."_id" : ObjectId("50398f04fe9dca5a555cab3f")
36.}
37.>

上面,我们分别向数据库mylearndb, mytestdb, admin 添加了3个用户,这里需要注意,往admin库中添加的用户就是超级用户(数据库管理员),经过认证的数据库管理员,可以操作任何数据库!添加完用户后,我们重启mongod服务,此时要加上--auth选项,开启安全认证,然后测试如下:

01.> use mylearndb;
02.switched to db mylearndb
03.> db.users.insert({"name" : "jimmy", "age":34});
04.unauthorized
05.> db.auth("jimmy", "1");
06.1
07.> db.users.insert({"name" : "jimmy", "age":34});
08.> use admin;
09.switched to db admin
10.> db.auth("Green", "1");
11.1
12.> use mytestdb;
13.switched to db mytestdb
14.> db.users.insert({"name":"tom", "age":32});
15.>

上例中,我们先连接数据库mylearndb,向一个集合插入文档,提示未认证,我们使用相应的用户名密码认证后,插入成功。然后我们切换到admin数据库中,通过了管理员认证,然后我们可以操作各种数据库了,包括还未认证的mytestdb数据库!这里需要注意,在哪个数据库中插入的用户,就要在哪个数据库中认证,因此管理员账号必须在admin数据库下认证! 

MongoDB还支持只读用户,调用addUser函数,第三个参数设置为true即可,如下:

01.> db.addUser("test", "q", true);
02.{ "n" : 0, "connectionId" : 3, "err" : null, "ok" : 1 }
03.{
04."user" : "test",
05."readOnly" : true,
06."pwd" : "64a4777ccfe889e32052edcd2b1c46ba",
07."_id" : ObjectId("50399325591704ec2536c2bc")
08.}
09.>

在该数据库下,该用户只可以读,不可以进行写操作。 

MongoDB将用户信息保存在相应数据库的system.users集合中,如果我们要删除一个用户,直接删除这个集合的相应文档即可!

01.> use mylearndb;
02.switched to db mylearndb
03.> db.system.users.find();
04.{ "_id" : ObjectId("50398ec4fe9dca5a555cab3d"), "user" : "jimmy", "readOnly" : false, "pwd" :"265134bf5a25fa7d91d60fba1555ba3b" }
05.{ "_id" : ObjectId("50399325591704ec2536c2bc"), "user" : "test", "readOnly" : true, "pwd" :"64a4777ccfe889e32052edcd2b1c46ba" }
06.> db.system.users.remove({"user":"test"});
07.> db.system.users.find();
08.{ "_id" : ObjectId("50398ec4fe9dca5a555cab3d"), "user" : "jimmy", "readOnly" : false, "pwd" :"265134bf5a25fa7d91d60fba1555ba3b" }
09.>

MongoDB的认证是与数据库的连接绑定在一起,即在同一个连接下,对一个数据库的验证进行一次即可。如果驱动程序使用了连接池,或因为故障切换到另外一个节点,连接改变了,所有的认证必须重新进行一遍,有些驱动程序将这些透明化,但有些没有,必须显示重新进行认证。这是MongoDB认证的一个弊端,所以建议不启用数据库认证,将用户认证转移到应用层来处理! 

除了上面提到的用户认证外,我们使用MongoDB时,还有一些安全点需要进行考虑。比如MongoDB的传输协议默认是不加密的,mongod在启动会同时启动一个http服务(可通过启动选项--nohttpinterface进行关闭),数据库服务器端javascript脚本的执行(可通过--noscripting禁止任何服务器端脚本的执行)等。

 

3.备份 

做备份是管理任何数据库系统的一项非常重要的任务,我们在管理关系型数据库时,就经常将exp/expdp做成系统定时任务来对数据库进行备份。对于MongoDB备份同样重要,并且MongoDB提供了很多中备份方式,这边进行逐一讲解。 

一:数据目录直接备份 

MongoDB将所有的数据都保存在数据目录中(启动时通过--dbpath指定的那个目录),我们备份数据的最简单方式就是保存这个目录的一个副本即可。但这种方式有一个最显著的问题,就是在运行时的MongoDB数据目录上备份并不安全(除非服务器进行了完整的fsync,并不允许写入,这个我们马上就会说到),有可能我们做得备份本身就是破损的!采用这种方式做备份,最好是将服务器停掉,备份后,再重启!这个在实际应用中是不允许的,因此使用的也很少! 



二:利用mongodump和mongorestore 

MongoDB自带的两个工具。mongodump是一个能在运行时备份数据库的方法,其就是一个客户端,对运行的MongoDB进行查询,然后将数据保存到相应位置即可。向 MongoDB提供的所有工具一样,我们可以通过使用--help选项来看这个工具的具体用法,我们这边演示一下基本的使用方法: 

导出

1.mongodump -d mylearndb -o E:\mongobak\27017

通过-d选项指定导出的数据库,此处只可以指定一个数据库!在Windows平台下测试,如果不使用-d选项(导出所有数据库),mongodump会在数据库服务器上创建一个名称为“*”的空数据库,导出这个数据库时因为创建同名Windows目录(名为“*”)失败而报错,但不影响其他数据库的导出,建议导出时通过-d指定数据库!-o选项,指定导出的数据库的放置目录,mongodump会在该目录下创建一个于数据库同名的目录,将数据导入在这个目录中。mongodump还支持导出特定集合(-c选项,只可指定一个集合),导出特定文档(-q查询条件)等,需要时可以查阅各选项(通过--help)。 

导入:

1.mongorestore -d mybakdb --drop E:\mongobak\27017\mylearndb

-d选项指明导入的数据库,--drop指名如果有同名集合先将其删除再导入(如果不用该选项,会进行合并),最后跟上要导入的数据库目录即可!会将这个目录的所有集合和数据导入到mybakdb这个数据库中! 

使用mongodump虽然可以不用停机备份,但其也有一个缺点,就是无法备份实时数据,尤其当数据库服务在进行大量的写操作时,mongodump只是备份了某一个特定时间点的数据。

 

 

4.fsync和锁 

通过fsync和锁可以在MongoDB运行时,安全有效地使用复制数据目录的方式进行备份!fsync命令会强制服务器将所有缓冲区内容写入到磁盘!通过上锁,可以阻止数据库的进一步写入!下面演示具体做法:

01.> use admin;
02.switched to db admin
03.> db.runCommand({"fsync" : 1, "lock" : 1});
04.{
05."info" : "now locked against writes, use db.fsyncUnlock() to unlock",
06."seeAlso" : "http://www.mongodb.org/display/DOCS/fsync+Command",
07."ok" : 1
08.}
09.>

注意运行fsync命令需要在admin数据库下进行!通过执行上述命令,缓冲区内数据已经被写入磁盘数据库文件中,并且数据库此时无法执行写操作(写操作阻塞)!这样,我们可以很安全地备份数据目录了!备份后,我们通过下面的调用,来解锁:

1.> use admin;
2.switched to db admin
3.> db.$cmd.sys.unlock.findOne();
4.{ "ok" : 1, "info" : "unlock completed" }
5.> db.currentOp();
6.{ "inprog" : [ ] }
7.>

在admin数据库下解锁。通过执行db.currentOp()来确认解锁成功!通过fsync和写入锁的使用,可以非常安全地备份实时数据,也不用停止数据库服务。但其弊端就是,在备份期间,数据库的写操作请求会阻塞!

 

 

 

5.修复 

做备份是为了以备不测,比如停电,或自然灾害等,不管怎样,数据是安全的!但总有一些意外情况:不测发生了,但我们还没来得及备份!这时数据目录中的数据可能出于损毁状态,如果在这样的数据目录上启动服务,MongoDB会给出特定的提示!MongoDB提供了修复数据目录的启动方式,就是在启动服务时使用选项--repair。修复过程就是,将所有的文档导出后立即导入,忽略无效的错误文档。并且需要将所有的索引重新建立!修复后,我们重新启动服务即可! 
对于大数据量的数据库,恢复是一个非常耗时的操作!因为所有数据都需要验证,并且所有索引都需要重新建立! 
Shell中通过调用db.repairDatabase()可以在数据库服务运行时修复特定的数据库(也可通过运行命令的方式进行,命令参数为:{"repairDatabase" :1})! 
修复数据库是万不得已才进行的,最佳实践是经常备份数据库,并且利用数据库的复制功能(马上会讲到)来实现故障恢复!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics