在perl中获取mongo db的fsynclock状态

时间:2013-02-08 00:33:18

标签: perl mongodb locking

我正在尝试构建一个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()'),但我有点迷失。

谢谢!

2 个答案:

答案 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的洞察力,它完美无缺

相关问题