2013-02-08 23 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的洞察力,雖然,它的工作完美