web-dev-qa-db-ja.com

インデックスの作成時にMongoクエリが長時間ハングするのはなぜですか?

シャーディングを使用して、単一のMongoインスタンスをMongoクラスターに移行しています。まだシャーディングを開始していません。しかし、インデックスを追加しようとすると、コレクションにクエリを実行できないことがわかりました。現在のMongoインスタンスにはこの問題はありません。現在のMongoでは、インデックス作成とコレクションのクエリを同時に適用できます。

これは、新しいクラスターにインデックスを作成するために実行するコマンドです。

mongos> db.lc_data.ensureIndex({"name": 1})

次に、別のターミナルを開いて、同じデータベース内の1つまたは複数のコレクションにクエリを実行します。

mongos> db.lc_other.find()

クエリがハングします!なぜこれが起こるのですか?

4
angelokh

MongoDB 3.2と同様に、これは フォアグラウンドインデックスビルド の予想される動作です。

デフォルトでは、インデックスを作成すると、データベースの他のすべての操作がブロックされます。コレクションにインデックスを作成する場合、コレクションを保持するデータベースは、インデックスの作成が完了するまで読み取りまたは書き込み操作に使用できません。すべてのデータベース(listDatabasesなど)で読み取りまたは書き込みロックが必要な操作は、フォアグラウンドインデックスの作成が完了するまで待機します。

既存の重要なデータがあるコレクションに新しいインデックスを作成するときにこの動作を回避するには、代わりにバックグラウンドでインデックスを作成する必要があります。

mongos> db.lc_data.ensureIndex({"name": 1}, {background:true})

MongoDB 2.4以降では、複数のインデックスをバックグラウンドで構築できます。詳細については、「 バックグラウンドインデックスのビルド 」を参照してください。

また、MongoDBの課題トラッカーでup-vote/watch SERVER-20960:Default index build option support in config/runtime とすることもできます。これは、デフォルトのインデックスビルドタイプを構成可能にする機能リクエストです(例:デフォルトはバックグラウンドインデックスビルドです)。

3
Stennie

バックグラウンドインデックスにも独自の問題があります。レプリカセットを実行している場合は、「ローリング」ビルドを実行することをお勧めします

  1. レプリカセットからセカンダリを取り出す
  2. インデックスを作成する
  3. セカンダリをレプリカセットに戻し、同期するまで待ちます。

これは、本番環境で大規模なインデックスを構築するための最も安全なオプションであることがわかりました。本番環境でこれを開始する前に、レプリケーションウィンドウが十分に大きいことを確認してください。私のブログ投稿の詳細-

2
Dharshan

MongoDBがスタンドアロンモードで実行されている場合は、新しいインデックスを作成する際のバックグラウンドオプションを使用することをお勧めします。また、 Sparse indexを使用することをお勧めします。次のリンクもご覧ください。 インデックス作成戦略 。災害復旧時にmongorestoreを使用している場合も、バックグラウンドインデックスを作成すると役立つ場合があります。

0
user3526905