我正在尝试构建一个nagios检查以检查mongoDB被锁定多长时间使用fsyncLock()进行备份(如果iSCSI快照脚本爆炸并且mongo未被解锁)
我在考虑使用简单的
$currentLock->run_command({currentOp => 1})
$isLocked = $currentLock->{fsyncLock}
但似乎run_command()还不支持currentOp。 (如那里所见:https://github.com/MLstate/opalang/blob/master/lib/stdlib/apis/mongo/commands.opa)
Woudl有人建议如何检查mongo是否被perl脚本锁定?如果没有,我想我会去做一些狂欢。我正在考虑使用db.eval('db.currentOp()'),但我有点迷失。
谢谢!
答案 0 :(得分:2)
你是对的,run_command
不支持直接执行currentOp
。但是,如果我们查看db.currentOp
shell中mongo
的实现,我们可以看到它是如何工作的:
> db.currentOp
function (arg) {
var q = {};
if (arg) {
if (typeof arg == "object") {
Object.extend(q, arg);
} else if (arg) {
q.$all = true;
}
}
return this.$cmd.sys.inprog.findOne(q);
}
因此,我们可以在Perl端查询特殊集合$cmd.sys.inprog
,以获得将在shell中返回的相同inprog
数组。
use strict;
use warnings;
use MongoDB;
my $db = MongoDB::MongoClient->new->get_database( 'test' );
my $current_op = $db->get_collection( '$cmd.sys.inprog' )->find_one;
当服务器未锁定时,它将返回$current_op
中的结构,如下所示:
{
'inprog' => [
{
'connectionId' => 53,
'insert' => {},
'active' => bless( do{\(my $o = 0)}, 'boolean' ),
'lockStats' => {
'timeAcquiringMicros' => {
'w' => 1,
'r' => 0
},
'timeLockedMicros' => {
'w' => 9,
'r' => 0
}
},
'numYields' => 0,
'locks' => {
'^' => 'w',
'^test' => 'W'
},
'waitingForLock' => $VAR1->{'inprog'}[0]{'active'},
'ns' => 'test.fnoof',
'client' => '127.0.0.1:50186',
'threadId' => '0x105a81000',
'desc' => 'conn53',
'opid' => 7152352,
'op' => 'insert'
}
]
};
在fsyncLock()
期间,您将获得一个空的inprog
数组,但您将拥有一个有用的info
字段和预期的fsyncLock
布尔值:
{
'info' => 'use db.fsyncUnlock() to terminate the fsync write/snapshot lock',
'fsyncLock' => bless( do{\(my $o = 1)}, 'boolean' ), # <--- that's true
'inprog' => []
};
所以,把它们放在一起,我们得到:
use strict;
use warnings;
use MongoDB;
my $db = MongoDB::MongoClient->new->get_database( 'fnarf' );
my $current_op = $db->get_collection( '$cmd.sys.inprog' )->find_one;
if ( $current_op->{fsyncLock} ) {
print "fsync lock is currently ON\n";
} else {
print "fsync lock is currently OFF\n";
}
答案 1 :(得分:2)
我实际上决定在bash中切换一个解决方案(稍后我想对数据做更容易):
currentOp=`mongo --port $port --host $host --eval "printjson(db.currentOp())"`
然后某种grep -Po '"fsyncLock" : \d'
感谢Perl的洞察力,它完美无缺