0

ローカルで実行されているMongoDBの使用可能なすべての接続を使い果たし、次のエラーメッセージが表示されるスクリプトがあります。

pymongo.errors.AutoReconnect: [Errno 4] Interrupted system call

/var/log/mongodb/mongod.logのエラーメッセージは次のとおりです。

[initandlisten] connection refused because too many open connections: 819

Mongo-Shellは、スクリプトが呼び出されているときに次の出力を提供します。

> db.serverStatus().connections
{ "current" : 1, "available" : 818 }  // Script not yet started
> db.serverStatus().connections
{ "current" : 400, "available" : 419 }  // Losing connections
> db.serverStatus().connections
{ "current" : 638, "available" : 181 }
> db.serverStatus().connections
{ "current" : 804, "available" : 15 }
> db.serverStatus().connections
{ "current" : 819, "available" : 0 }  // Script terminates
> db.serverStatus().connections
{ "current" : 1, "available" : 818 }  // Script terminated

元のスクリプトを投稿することはできませんが、次の「サニタイズされた」スニペットがアイデアを与えることを願っています。基本的に、私はいくつかのコレクションにわたってあらゆる種類の異なるクエリと更新を実行しています。

最も重要なのは、11個のデータベースステートメントのうち5個だけが接続を解放しない場合があることです。他の6つのステートメントは、ステートメントの前にあったのと同じ数の空き接続を常に残します。

mc = pymongo.Connection()
db = mc.database

def available():
    """ Return the number of available connections """
    return db.command("serverStatus")['connections']['available']

def process():
    while True:
        # ...
        # Connections lost:
        conns = available()
        coll_a = db.coll_a.find_and_modify(
                query={'x': x},
                update={'$pop': {'x': -1}},
                fields={'x': 1})
        if conns > available():
            print('Fewer connections')
        # ...
        # No connections lost:
        db.coll_a.update({'x': x}, {'$pullAll': {'x': [x]}})
        # ...
        # No connections lost:
        coll_d = db.coll_d.find_and_modify(
                query={'x': x,},
                update={'$set': {'x': x}},
                fields={'x': 1})
        # ...
        # No connections lost:
        coll_b_cursor = db.coll_b.find({'x': x}, {'x': 1})
        # ...
        # No connections lost:
        coll_e_cursor = db.coll_e.find({'$or': [{'x': x}, {'x': x}]})
        # ...
        for item in coll_e_cursor:
            # No connections lost:
            coll_b = db.coll_b.find({'x': x}).count()
        # ...
        # No connections lost:
        coll_b_cursor = db.coll_b.find({'x': x}, {'x': x})
        # ...
        for x in y:
            if x:
                # Connections lost:
                conns = available()
                db.coll_b.update({'x': x}, {'$unset': {'x': 1}})
                if conns > available():
                    print('Fewer connections')
            # ...
            # Connections lost:
            conns = available()
            coll_b = db.coll_b.find_and_modify(
                    query={'x': x},
                    update={'$set': {'x': x}},
                    fields={'x': 1},
                    upsert=True)
            if conns > available():
                print('Fewer connections')
            # ...
            # Connections lost:
            conns = available()
            coll_c_1 = db.coll_c.find_one({'x': x})
            coll_c_2 = db.coll_c.find_one({'x': x})
            if conns > available():
                print('Fewer connections')
        # ...
        # Connections lost:
        conns = available()
        db.coll_b.update({'x': x}, {'$unset': {'x': 1}})
        if conns > available():
            print('Fewer connections')
  • 接続を解放しないステートメントと解放するステートメントの違いは何ですか?
  • PyMongoまたはMongoDBは、すべての状況で接続を解放するべきではありませんか?

PyMongo:2.2.1

MongoDB:2.0.6

4

1 に答える 1

1

接続が失われたのは、思われる場所ではなく .

process() のどこかでスレッドが開始されたことを見落としていました。

threading.Thread(target=target, args=(args)).start()

このスレッドはデータベース呼び出しを行いました。

process() の while ループは十分に高速で、多くのスレッドが同時に実行されていました。利用可能なすべてのデータベース接続を使い果たしています。

これらのスレッドを起動しないと、使用可能なデータベース接続の数は一定のままです。

于 2012-07-19T07:15:09.830 に答える