MongoDB Lock use caveats

在mongodb中使用db.runCommand({fsync:1,lock:1})可以将内存中未写入磁盘的信息写入磁盘,并锁住对数据库改写的操作,读操作可以继续。
一般用于数据库的SNAPSHOT。
由于MONGODB使用的是read/write锁,即读写是冲突的.因此使用lock有几个需要注意的地方,用得不好可能导致需要重启数据库。
例如:
session A:
> db.runCommand({fsync:1,lock:1})
{
        "info" : "now locked against writes, use db.$cmd.sys.unlock.findOne() to unlock",
        "ok" : 1
}
> db.currentOp()                 
{ "inprog" : [ ] }

# 此时不做任何写操作,登录到session B,C.
session B:
MongoDB shell version: 1.6.4
connecting to: 127.0.0.1:5281/admin
> db.auth("digoal","DIGOAL")
这里卡住

session C:
MongoDB shell version: 1.6.4
connecting to: 127.0.0.1:5281/admin
> db.auth("digoal","DIGOAL")
这里卡住

session A:
> db.currentOp()                 
{
        "inprog" : [
                {
                        "opid" : 35,
                        "active" : false,
                        "lockType" : "read",
                        "waitingForLock" : true,
                        "op" : "query",
                        "ns" : "?dmin.tbl_test",
                        "query" : {

                        },
                        "client" : "127.0.0.1:33874",
                        "desc" : "conn"
                },
                {
                        "opid" : 34,
                        "active" : true,
                        "lockType" : "write",
                        "waitingForLock" : true,
                        "secs_running" : 18,
                        "op" : "query",
                        "ns" : "?",
                        "query" : {
                                "authenticate" : 1,
                                "user" : "digoal",
                                "nonce" : "28d27268246c42b8",
                                "key" : "2b29a029bea30bd16c1bc2ba3b53396f"
                        },
                        "client" : "127.0.0.1:43981",
                        "desc" : "conn"
                }
        ],
        "fsyncLock" : 1,
        "info" : "use db.$cmd.sys.unlock.findOne() to terminate the fsync write/snapshot lock"
}

#释放锁
> db.$cmd.sys.unlock.findOne();  
{ "ok" : 1, "info" : "unlock requested" }
> db.currentOp()               
{ "inprog" : [ ] }

session B:
认证通过
session C:
认证通过

session A:
# 再次加锁
> db.runCommand({fsync:1,lock:1})
{
        "info" : "now locked against writes, use db.$cmd.sys.unlock.findOne() to unlock",
        "ok" : 1
}

session B:
> db.tbl_test.find()
{ "_id" : ObjectId("4d003b9c23ce070b7227bc5f"), "a" : 1 }

session C:
> db.tbl_test.find()
{ "_id" : ObjectId("4d003b9c23ce070b7227bc5f"), "a" : 1 }

session D:
MongoDB shell version: 1.6.4
connecting to: 127.0.0.1:5281/admin
> db.auth("digoal","DIGOAL")
这里卡住

再次回到session B,C:
> db.tbl_test.find()
卡住了

session A:
> db.currentOp()                 
{
        "inprog" : [
                {
                        "opid" : 45,
                        "active" : true,
                        "lockType" : "write",
                        "waitingForLock" : true,
                        "secs_running" : 63,
                        "op" : "query",
                        "ns" : "?",
                        "query" : {
                                "authenticate" : 1,
                                "user" : "digoal",
                                "nonce" : "8240c091997df278",
                                "key" : "0c848429a5a973e3b25b10c906fc9211"
                        },
                        "client" : "127.0.0.1:45638",
                        "desc" : "conn"
                },
                {
                        "opid" : 46,
                        "active" : false,
                        "lockType" : "read",
                        "waitingForLock" : true,
                        "op" : "query",
                        "ns" : "?dmin.tbl_test",
                        "query" : {

                        },
                        "client" : "127.0.0.1:43981",
                        "desc" : "conn"
                },
                {
                        "opid" : 49,
                        "active" : true,
                        "lockType" : "write",
                        "waitingForLock" : true,
                        "secs_running" : 20,
                        "op" : "query",
                        "ns" : "?",
                        "query" : {
                                "authenticate" : 1,
                                "user" : "wapprepaid",
                                "nonce" : "5ae8f2534427f6d2",
                                "key" : "01e013f0a035f86455d807b4d94f1e44"
                        },
                        "client" : "172.16.10.74:2637",
                        "desc" : "conn"
                }
        ],
        "fsyncLock" : 1,
        "info" : "use db.$cmd.sys.unlock.findOne() to terminate the fsync write/snapshot lock"
}

认证时需要加载WRITE锁,导致读被堵塞。
另外需要注意的是,如果SESSION A,也就是允许fsync和lock的SESSION被堵塞了的话,只能重启数据库了。
重启前KILL -9 ,删除lock文件.

时间: 2024-12-22 19:46:23

MongoDB Lock use caveats的相关文章

mongdb备份恢复

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://navyaijm.blog.51cto.com/4647068/1686280 一.物理备份(拷贝文件) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49

解决mongodb在ubuntu下启动失败,提示couldn‘t remove fs lock errno:9 Bad file descriptor的错误_MongoDB

按照官网上的安装方法: 在ubuntu系统下有可能出现如下错误: couldn't remove fs lock errno:9 Bad file descriptor 此时需要修改文件所有者 $ sudo mkdir -p /data/db/ $ sudo chown 'USERNAME' /data/db 其中第一句是建立你的数据库文件夹,第二句修改该文件夹的所有者 之后就可以成功启动mongodb了 参考:stackoverflow.com/questions/15229412/unabl

mongoDB, warning: ClientCursor::yield can't unlock b/c of recursive lock ns:

某库的日志里报一堆这样的警告,  warning: ClientCursor::yield can't unlock b/c of recursive lock ns: 加索引解决 源码里有一段相关的代码如下 :  void ClientCursor::staticYield( int micros , const StringData& ns , Record * rec ) { killCurrentOp.checkForInterrupt( false ); { auto_ptr<RW

MongoDB实战(2)工具集与特殊魔术方法

一.MongoDB启动方式 MongoDB除了支持命令行的启动方式还支持配置文件启动通过读取启动配置文件的方式来启动数据库比方说配置文件如下 则可以使用如下命令 ./mongod -f /etc/mongodb.conf MongoDB参数说明 dbpath: 数据文件存放路径每个数据库会在其中创建一个子目录用于防止同一个实例多次运行的mongod.lock也保存在此目录中. logpath 错误日志文件 logappend 错误日志采用追加模式默认是覆写模式 bind_ip 对外服务的绑定ip

mongoDB第六讲

  ?mongoDB启动配置详解 1.启动项 mongod --help 1.1利用config配置文件来启动数据库改变端口为8888 mongodb.conf文件 dbpath = D:appmongodata port = 8888 启动文件 mongod.exe --config mongodb.conf shell文件 mongo 127.0.0.1:8888 2.停止mongoDB服务 1.1ctrl+c 组合键可以关闭数据库 1.2admin数据库命令关闭数据 use admin d

java使用mongoDB

  我的电脑环境: win7 64位系统 1.安装mongoDB 去官网下载http://www.mongodb.org/downloads 选择适合你系统的版本. 下载好后解压,我是解压在d盘 ,这就算安装好了.截图如下: 如何启动? 先建立数据和日志存放的地点?看上面我的截图. 然后就是启动了. 命令行下: D:mongodbbinmongod.exe -dbpath=d:mongodbdata D:mongodbbinmongod.exe -logpath=d:mongodblogs 每次

TokuMX, MongoDB and InnoDB versus the insert benchmark with disks

I used the insert benchmark on servers that use disks in my quest to learn more about MongoDB internals. The insert benchmark is interesting for a few reasons. First while inserting a lot of data isn't something I do all of the time it is something f

a mongodb 1.8.1 unauthorized BUG when I change replicaSet config in Primary

今天在给一组mongoDB replicaSet修改配置的时候,遇到一个BUG. 环境是这样的: 3台服务器组成的3 full nodes replicaSet. 由于其中一台服务器配置比较差,准备调整"priority" : 0 让这台节点不会自动转会为primary. 引起BUG的是开启了keyFile(1.8.1使用keyFile来实现member之间的认证),也就是replicaSet的authorization.(看样子目前replicaSet的authorization还是

MongoDB学习系列(3)--解决MongoDB Unexpected Shutdown问题

晚上准备继续学习 PHP+MongoDB,点击Run_MongoDB_Service.bat文件,这个文件是我写的bat文件,就是快速启动MongoDB.但是命令 行一闪而过,我很奇怪.昨天晚上写代码还是正常的,怎么今天用就不正常了.我只好手动敲一遍命令.界面好像和之前不一样,个人觉得应该是出错了.错误界面 如下: 主要信息有2个: 1.Unclean shutdown detected. 2.可以恢复的参考:http://docs.mongodb.org/manual/tutorial/rec