2013-02-08 20 views
1

我正在尝试构建一个nagios检查以检查mongoDB已被多长时间用于备份目的的fsyncLock()锁定(如果iSCSI快照脚本爆炸并且mongo没有被解锁为例)在perl中获取mongo db的fsynclock状态

我想使用一个简单的

$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()'),但我有点失落。

谢谢!

回答

2

你是对的,run_command不支持直接做currentOp。但是,如果我们看一下在mongodb.currentOp的实施,我们可以看到它是如何工作的引擎盖下:

> 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得到相同的inprog阵列这将在shell中返回。

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

嗯,这是一个令人惊讶的准确的答案,工程就像一个魅力。非常感谢! –

1

其实我决定改在bash的解决方案(方便我想以后的数据做):

currentOp=`mongo --port $port --host $host --eval "printjson(db.currentOp())"` 

然后某种grep -Po '"fsyncLock" : \d'

感谢Perl的洞察力,虽然,它的工作完美