使用mongod命令启动
查看帮助使用mongod --help,选项如下:
--datapath
指定数据目录;默认是/data/db/ .每个mongod进程都需要独立的目录,如果有3个mongod实例,必需有3个独立的目录。
当MongoDB启动时会创建mongod.lock文件,用于其它mongod进程使用该目录。如果使用同一个目录启动另一个mongod进程会报错:
"Unable to acquire lock forlockfilepath: /data/db/mongod.lock."
--port
指定服务器监听的端口号,默认是27017。要运行多个mongod进程,则要指定不同的端口号。如果启动时端口号被占用,则报错:
"Address already in use for socket:0.0.0.0:27017"
--fork
以守护进程的方式运行MongoDB,创建服务器进程。
--logpath
指定日志文件输出路径。如果日志文件不存在会创建它,如果已经存在则会覆盖它,清除原来的日志记录。如果想要保留原来的日志,还需要使用--logappend选项
--rest
打开简单的REST API,要想访问监控页面的命令列表,要使用--rest选项
下面mongod命令启动实例:
# ./mongod --port 5586 --fork --logpathmongod.log
注意:要养成经常看日志的习惯,特别是当实初次安装并启动MongoDB的时候。
使用配置文件启动
当需要的配置非常多或是要自动化启动MongoDB的时会用到这个。指定文件可以用-f或--config选项,如:
# mongod -f /etc/mongod.conf
# cat /etc/mongod.conf
# Start MongoDB as a daemon on port 5586
port = 5586
fork = true # daemonize it!
logpath = mongodb.log
停止MongoDB最基本的方法就是向MongoDB发送一个SIGINT或SIGTERM信号。如:
# kill -2 10014 (SIGINT)
# kill 10014 (SIGTERM)
如果服务器是作为前台进程运行在终端的,可直接按Ctrl+C
当MongoDB收到SIGINT或SIGTERM信号时,会稳妥了退出。也就是说会等到当前的操作或文件预分配完成(需要一些时间),关闭所有打开的连接,将缓存的数据刷到硬盘,然后关闭。
注意:不要用SIGKILL(kill -9)这种信号,这样会导致数据库直接关闭,可能会损坏文件。
另一种稳妥的方式是使用shutdown 命令,({"shutdown":1})。这是管理命令,要在admin库下使用。如:
> db.shutdownServer()
shutdown command only works with the admindatabase; try 'use admin'
> use admin
switched to db admin
> db.shutdownServer()
Thu Feb 25 10:35:25.567DBClientCursor::init call() failed
server should be down...
Thu Feb 25 10:35:25.582 trying reconnect to127.0.0.1:27017
Thu Feb 25 10:35:25.585 reconnect127.0.0.1:27017 failed couldn't connect to server 127.0.0.1:27017
管理页面
MongoDB自带的默认管理监控页面端口是28017(比--port选项多1000),如:http://localhost:28017
也可在启动MongoDB时关闭管理接口,使用--nohttpinterface
serverStatus
要获取运行中的MongoDB服务器的统计信息,最基本的工具就是serverStatus命令
>db.runCommand({"serverStatus":1})
{
"host" : "racdb",
"version" : "2.4.14",
"process" : "mongod",
"pid" : 14098,
"uptime" : 687,
"uptimeMillis" : NumberLong(687456),
"uptimeEstimate" : 679,
"localTime" : ISODate("2016-02-25T02:51:59.491Z"),
"asserts" : {
"regular" : 0,
"warning" : 0,
"msg" : 0,
"user" : 0,
"rollovers" : 0
},
"backgroundFlushing" : {
"flushes" : 11,
"total_ms" : 1,
"average_ms" :0.09090909090909091,
"last_ms" : 0,
"last_finished" :ISODate("2016-02-25T02:51:32.061Z")
},
"connections" : {
"current" : 1,
"available" : 818,
"totalCreated" :NumberLong(3)
......
也可以通过监控页面获取serverStatus命令信息,和其它管理命令信息。下面是值的解释:
"globalLock" 的值表示全局写入锁占用服务器的时间(微秒)。
"mem" 包含服务器内存映射了多少数据,服务器的虚拟内存和常驻内存的占用情况(单位M)
"indexCounters" 表示B树索引在磁盘检索("misses")和内存检索("hits")的次数。如果这个比值上升就考虑加内存了,否会影响性能。
"backgroudFlushing" 表示后台做了多少次fsync以及用了多少时间。
"opcounters" 文档非常重要,包括每种主要操作的次数。
"asserts" 统计断言的次数
serverStatus统计的信息是在服务器启动是开始计算的,如果过大就会复位。当发生复位时,所有计数器都会复位,"asserts"中的"rollovers"就会增加。
mongostat
mongostat能在系统中输出一些serverStatusr的重要信息,每秒输出一行,如:
[root@racdb ~]# mongostat
connected to: 127.0.0.1
insert query update delete getmore command flushes mapped vsize res faults locked db idx miss% qr|qw ar|aw netIn netOut conn time
*0 3 *0 *0 0 1|0 0 288m 854m 49m 0 admin:0.0% 0 0|0 0|0 62b 2k 1 11:19:33
*0 *0 *0 *0 0 1|0 0 288m 854m 49m 0 test:0.0% 0 0|0 0|0 62b 2k 1 11:19:34
*0 *0 *0 *0 0 1|0 0 288m 854m 49m 0 test:0.0% 0 0|0 0|0 62b 2k 1 11:19:35
*0 *0 *0 *0 0 1|0 0 288m 854m 49m 0 test:0.0% 0 0|0 0|0 62b 2k 1 11:19:36
第三方插件
好多监控系统都提供了MongoDB的插件,如 Nagios, Munin, Ganglia, Cacti。
登录http://dochub.mongodb.org/core/monitoring查看与监控工具有关的文档。
每个MongoDB实例中的数据库可以有多个用户。如果开启了安全性检查,只有认证的用户才对数据库执行读写操作。admin数据库的用户作为超级用户(即管理员)。在认证之后管理员可以读写所有数据库,并执行特定的命令,如listDatabases、shutdown
在开启安全检查之前,一定要有个管理员账号。如下面例子开始安全检查(之前shell连接是没有开启)
--添加管理员用户
[root@racdb ~]# mongo
MongoDB shell version: 2.4.14
connecting to: test
> show users
>db.addUser("root","root123")
{
"user" : "root",
"readOnly" : false,
"pwd" : "81c5bca573e01b632d18a459c6cec418",
"_id" : ObjectId("56cec6f70a7cdb43b6b66e62")
}
--添加一个test数据库的可读写用户
>db.addUser("test_user","test123")
{
"user" : "test_user",
"readOnly" : false,
"pwd" : "77aef110dfb9d6efb45080d5f12a9a4c",
"_id" : ObjectId("56cec88c0a7cdb43b6b66e63")
}
--添加一个test数据库的只读用户
>db.addUser("test2","test456",true)
{
"user" : "test2",
"readOnly" : true,
"pwd" : "e090b01f7663103a3ee00a72fff6181d",
"_id" : ObjectId("56cec8ca0a7cdb43b6b66e64")
}
注意:
调用addUser必需有相应数据库的写权限,这里可以对所有数据库调用addUser,因为还没有开启安全检查。
addUser不仅可添加用户,还可以用户口令和只读状态。
--现在重启服务器后,加入--auth命令选项,开启安全检查。
[root@racdb ~]# mongod -f /etc/mongod.conf--rest --auth
about to fork child process, waiting untilserver is ready for connections.
forked process: 26831
all output going to:/var/log/mongo/mongod.log
child process started successfully, parentexiting
[root@racdb ~]# mongo
MongoDB shell version: 2.4.14
connecting to: test
--使用普通账号
> show collections
Thu Feb 25 17:38:29.716 error: {
"$err" : "not authorized for query ontest.system.namespaces",
"code" : 16550
} at src/mongo/shell/query.js:128
>db.auth("test_user","test123")
1
> show collections
analytics
blog
blog.posts
--使用管理员账号
> use admin
switched to db admin
> show dbs
Thu Feb 25 17:42:32.267 listDatabasesfailed:{ "ok" : 0, "errmsg" : "unauthorized" } atsrc/mongo/shell/mongo.js:46
>db.auth("root","root123")
1
> show dbs
admin 0.203125GB
local 0.078125GB
test 0.203125GB
在开启安全检查后,打开http://localhost:28017/监控页面时会出现登录界面。
认证用户管理
数据库用户帐号以文档的形式存储在system.users集合里。
> db.system.users.find()
{ "_id" :ObjectId("56cec88c0a7cdb43b6b66e63"), "user" :"test_user", "readOnly" : false, "pwd" :"77aef110dfb9d6efb45080d5f12a9a4c" }
{ "_id" :ObjectId("56cec8ca0a7cdb43b6b66e64"), "user" :"test2", "readOnly" : true, "pwd" :"e090b01f7663103a3ee00a72fff6181d" }
--删除用户
>db.auth("test_user","test123")
1
>db.system.users.remove({"user":"test2"})
>db.auth("test2","test456")
Error: 18 { code: 18, ok: 0.0, errmsg:"auth fails" }
0
数据文件备份
MongoDB将所有数据都存放在数据目录下,默认目录是/data/db,在启动MongoDB启动时在--dbpath指定。这种方法只需要对数据目录复制备份副本就可以了。
但需要停止MongoDB服务再进行备份,否服务运行时直接拷贝数据文件目录会不安全,可能会损坏数据文件。所以这其实属于一种冷备份的方法,不太理想。
mongodmp和mongorestore
mongodmp可在MongoDB运行时备份的方法,可对运行的MongoDB做查询,将查询结果写入磁盘。即是一种热备份的方法。
注意:
mongodmp是普通的查询机制,所以产生的备份不一定是实时的数据库的快照,备份过程中数据库可能生产变化。
mongodmp在备份时可能数据库的性能产生影响。
--帮助选项
[root@racdb ~]# mongodump--help
Export MongoDB data to BSONfiles.
options:
--help produce helpmessage
-v [ --verbose ] be more verbose (includemultiple times
formore verbosity e.g. -vvvvv)
--version print theprogram's version and exit
-h [ --host ] arg mongo host to connect to (<set
name>/s1,s2 for sets)
--port arg server port. Canalso use --host
hostname:port
--ipv6 enable IPv6support (disabled by
default)
-u [ --username ] arg username
-p [ --password ] arg password
--authenticationDatabase arg user source (defaults to dbname)
--authenticationMechanism arg (=MONGODB-CR)
authentication mechanism
--dbpath arg directly accessmongod database files
in thegiven path, instead of
connecting to a mongod server -needs
to lockthe data directory, so cannot
be used if a mongodis currently
accessing the same path
--directoryperdb each db is in a separatedirectly
(relevant only if dbpath specified)
--journal enable journaling(relevant only if
dbpathspecified)
-d [ --db ] arg database to use
-c [ --collection ] arg collection to use (somecommands)
-o [ --out ] arg (=dump) output directory or "-"for stdout
-q [ --query ] arg json query
--oplog Use oplog for point-in-time
snapshotting
--repair try to recover acrashed database
--forceTableScan force a table scan (donot use
$snapshot)
Mongorestore是MongoDB的恢复工具,获取mongodump的输出结果,并将备份插入运行的MongoDB中。下面的例子:从数据库test到backup目录的热备份,接着恢复到foo数据库。
# mongodump-u root -p root123 -d test -o backup
connected to: 127.0.0.1
Fri Feb 26 17:41:43.384 DATABASE: test to backup/test
Fri Feb 26 17:41:43.385 test.system.indexes tobackup/test/system.indexes.bson
Fri Feb 26 17:41:43.424 30 objects
Fri Feb 26 17:41:43.424 test.my_collection tobackup/test/my_collection.bson
# #mongorestore -u root -p root123 --authenticationDatabase admin -d foo --dropbackup/test
-d代表要恢复的数据库(foo)
--drop指恢复前要删除集合(如果存在),否则数据会与现有的集合数据合并,可能会覆盖文档。
--authenticationDatabase认证用户的数据库(如是admin,就是管理员用户)
--help可查看帮助文档。
MongoDB的fsync命令能在MongoDB运行时复制数据目录还不会损坏数据。
fsycn命令会强制服务器将所有缓冲区写入磁盘,还可以选择上阻止对数据库的进一步写入,直到释放锁为止。写入锁是让fsync在备份时发挥作用的关键。如下,强制执行了fsync并获得了写入锁:
> use admin
switched to db admin
>db.runCommand({"fsync":1,"lock":1})
{
"info" : "now locked against writes, use db.fsyncUnlock()to unlock",
"seeAlso" :"http://dochub.mongodb.org/core/fsynccommand",
"ok" : 1
}
--可以查询
> db.cols.find()
{ "_id" :ObjectId("56aac1df4e61b6d9f84d17e0"), "bar" :"bar" }
--在写入文档时一直处于阻塞状态,直到解锁完成
>db.cols.insert({"name":"licz"})
至此,数据目录的数据是一致的,且为数据的实时快照。因为上了写入锁,可以安全了对数据目录副本用做备份。
备份好了,就要解锁:
> db.fsyncUnlock()
{ "ok" : 1, "info" :"unlock completed" }
> db.currentOp()
{ "inprog" : [ ] }
运行db.currentOp()是确保已经解锁了,初次执行可能会花些时间。
用fsync命令,就能非常灵活的备份,不用停掉服务器,也不牺牲备份的实时特性。要付出的代价就是一些写入操作被暂时阻塞了。
所以唯一不耽误读写还能保证实时快照的备份方式就是通过从服务器的备份
虽然上面说的几种数据库备份方式已经很灵活了,但是都不及在从服务器上备份。当以复制的方式运行MongoDB时,前面提到的备份技术不仅能在主服务器上,也能用在从服务器上,而且效果会更好。从服务器的数据几乎和主服务器同步。因为不太在乎从服务器会不会读写,
于是就能随意选择上面的几种备份方式:关停、转储和恢复工具或fsync命令。在从服务器上备份是MongoDB推荐的方式。(后面的文章进行讨论)
当由于机房停电或软件崩溃,数据库文件出现损坏时,MongoDB的内置的修复功能会试着恢复损坏的数据文件。
未能正常停止MongoDB后应该修复数据库。要是未正常停止,下次启动服务器备份时MongoDB会提示:
**************
old lock file: /data/db/mongod.lock.probably means unclean shutdown
recommend removing file andrunning --repair
see:http://dochub.mongodb.org/core/repair for more information
*************
修复所有数据库的方法就是在MongoDB启动时加上--repair参数,如:mongod --repair
修复原理:修复数据库的过程其实是,将所有的文档导出后然后再导入,忽略那些无效的文档。完成后会重新建立索引。数据量大的话会花很多时间,因为所有数据都要验证,所有索引都要重建。修复后可能会比以前少些文档,因为损毁的数据库被丢弃了。
注意:修复数据还能起到压缩数据的作用,闲置的空间(比如删除体积较大集合,或删除大量文档后)在修复后被重新收回。
修复运行中的某个数据库,要在shell中用repairDatabase,如下:
> db.repairDatabase()
{ "ok" : 1 }
--或是通过驱动程序来完成
>db.runCommand({"repairDatabase":1})
{ "ok" : 1 }
修复是损毁数据是不得已时的最后一招。尽可能稳妥地停掉服务器,利用复制功能实现故障恢复,经常做备份,这样才最有效的管理数据的手段。