AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

データが存在するコレクションでのインデックス構築

インデックス構築では、最適化された構築プロセスを使用し、インデックス構築の開始時と終了時にコレクションを排他ロックします。構築プロセスの残りの部分は、読み取り操作と書き込み(write)操作のインターリーブによって一時停止されます。インデックス構築プロセスとロック動作の詳細については、「インデックス構築プロセス」を参照してください。

レプリカセットまたはシャーディングされたクラスターに対するインデックスは、データを保持するすべてのレプリカセットメンバーに対して同時にビルドされます。プライマリには、データを保持する投票ノードについて、使用準備完了とインデックスをマークする前にビルドの完了が必要な、プライマリ自体を含めた最小数(コミットクォーラム)が設定されています。 「投票」ノードは、 がmembers[n].votes 0より大きい任意のレプリカセットノードです。詳細については、 「レプリケートされた環境でのインデックス構築」 を参照してください。

MongoDB 7.1 以降では、インデックス構築でのエラー報告が高速化され、障害回復力が高まります。 新しいindexBuildMinAvailableDiskSpaceMBパラメータを使用して、インデックスビルドに必要な最小ディスク容量を設定することもできます。これにより、ディスク容量が低すぎる場合はインデックスビルドが停止します。

次の表は、MongoDB 7.1 以降と以前のバージョンのインデックス構築動作を比較したものです。

MongoDB 7.1 以降の 動作
以前の MongoDB バージョンでの動作

重複キー エラーを除く、コレクションスキャンフェーズ中に見つかったインデックス エラーは直ちに返され、その後インデックスのビルドは停止します。 以前の MongoDB バージョンでは、インデックスビルドの終了間際に発生するコミットフェーズでエラーが返されます。 MongoDB 7.1 は、インデックス エラーを迅速に診断するのに役立ちます。 たとえば、互換性のないインデックス値の形式が見つかった場合は、すぐにエラーが返されます。

MongoDB 7.1 と比較して、インデックス構築エラーが返されるまでに長い時間がかかる可能性があります。このエラーはコミットフェーズのインデックス構築の終了間して返されるためです。

配置の回復力を強化。 インデックスビルドエラーが発生した場合、セカンダリノードはプライマリメンバーにインデックスビルドの停止をリクエストでき、セカンダリノードはクラッシュしません。 インデックスビルドを停止するリクエストは常に可能ではありません。ノードがすでにインデックスをコミットするために投票している場合、セカンダリはインデックスビルドの停止をリクエストできず、セカンダリはクラッシュします(MongoDB 7.0 以前と同様)。

インデックス構築エラーにより、セカンダリ ノードがクラッシュする可能性があります。

インデックス ビルドのためのディスク領域の管理を改善しました。 使用可能なディスク容量がindexBuildMinAvailableDiskSpaceMBパラメータで指定された最小値を下回ると、インデックスビルドが自動的に停止されることがあります。 ノードがすでにインデックスをコミットするために投票している場合、インデックスのビルドは停止されません。

使用可能なディスク容量が不足しても、インデックスの構築は停止しません。

注意

Atlas でのインデックス作成の詳細については、Atlas ドキュメントの「インデックス管理ページ 」を参照してください。

MongoDBの以前のバージョンでは、フォアグラウンドまたはバックグラウンドでのインデックスのビルドがサポートされていました。フォアグラウンドでのインデックス構築は高速で、より効率の高いインデックスデータ構造が生成されていましたが、構築中はインデックスされるコレクションの親データベースへの読取りおよび書き込みアクセスをすべてブロックする必要がありました。バックグラウンドでのインデックス構築は遅く、結果の効率も低いものでしたが、ビルド中にデータベースとそのコレクションへの読取りおよび書込みアクセスが可能でした。

インデックス構築では、構築の開始時と終了時にのみ、インデックスが作成されるコレクションに対して排他ロックが取得されるようになりました。構築プロセスの残りの部分では、バックグラウンドインデックス構築の生成動作を使用して、構築中にコレクションへの読み取りおよび書込みアクセスを最大化します。インデックス構築では、ロック動作の制限が緩いにもかかわらず、効率的なインデックスデータ構造が生成されます。

最適化されたインデックス構築のパフォーマンスは、最低でもバックグラウンド インデックス構築と同等です。構築プロセス中に更新がほとんどまたはまったく受信されないワークロードの場合、最適化されたインデックス構築は、同じデータに対するフォアグラウンド インデックス構築と同じくらい高速になります。

進行中のインデックス構築の進行状況を監視するには、db.currentOp() を使用します。

MongoDB では、createIndexesまたはそのシェルヘルパーcreateIndex()createIndexes()に指定されている場合は background インデックス構築は無視されます。

一意のインデックスなど、コレクションに制約を強制するインデックスの場合、 mongodはインデックスのビルド完了後に、既存のドキュメントと同時に書込まれたすべてのドキュメントをチェックし、それらの制約に違反しているかどうかをチェックします。 インデックス制約に違反するドキュメントは、インデックスのビルド中に存在する可能性があります。 ビルドの最後にインデックス制約に違反するドキュメントがある場合、 mongodはビルドを終了し、エラーをスローします。

たとえば、データが入ったコレクションinventoryを考えてみましょう。 管理者が、 product_skuフィールドに一意のインデックスを作成したいと考えています。 コレクション内のいずれかのドキュメントでproduct_skuの値が重複している場合でも、インデックスのビルドは正常に開始できます。 ビルドの最後に違反がまだ存在する場合、 mongodはビルドを終了し、エラーをスローします。

同様に、インデックス構築が進行中に、アプリケーションはproduct_sku の重複する値を持つdocumentを inventoryコレクションに正常に書き込むことができます。

制約違反によるインデックス構築失敗のリスクを軽減するには、以下の対策を取ります。

  • コレクション内のドキュメントがどれもインデックス制約に違反していないことを検証します。

  • 違反のない書き込み操作を保証できないアプリケーションからの、コレクションへの書き込みをすべて停止します。

複数のシャードに分散されたシャーディングされたコレクションの場合、1 つ以上のシャードに重複したdocumentを含むチャンクが含まれる場合があります。そのため、インデックスの作成操作は、一部のシャード(重複のないシャード)では成功するものの、他のシャード(重複のあるシャード)では成功しない場合があります。シャード間で不整合なインデックスが残らないようにするには、 からdb.collection.dropIndex() mongosを発行して、コレクションからインデックスを削除します。

この問題が発生するリスクを軽減するには、インデックスを作成する前に次の手順を実行します。

  • コレクション内のドキュメントがどれもインデックス制約に違反していないことを検証します。

  • 違反のない書き込み操作を保証できないアプリケーションからの、コレクションへの書き込みをすべて停止します。

デフォルトでは、サーバーは最大 3 つの同時インデックス構築を許可します。許可される同時インデックス構築の数を変更するには、 maxNumActiveUserIndexBuilds パラメータを変更します。

同時インデックス構築数が maxNumActiveUserIndexBuilds で指定された制限に達した場合、同時インデックス構築数が制限を下回るまで、サーバーは追加のインデックス構築をブロックします。

ターゲットコレクションの書き込み負荷が高いときにインデックスをビルドすると、書込みパフォーマンスが低下し、インデックス構築に通常よりも時間がかかる場合があります。

こうした場合、アプリケーションでコレクションに対する書込み操作を停止または削減するメンテナンスウィンドウの指定を検討します。このメンテナンスウィンドウ中にインデックス構築を開始します。

createIndexes は、コレクションでの 1 つ以上のインデックスの構築をサポートしています。createIndexes はメモリとディスク上の一時ファイルの組み合わせを使用してインデックスを構築します。デフォルトのメモリ制限は、createIndexes コマンドあたり 200 メガバイトで、そのコマンドでビルドされたすべてのインデックス間で均等に共有されます。例、1 つの createIndexes コマンドで 10 インデックスをビルドする場合、 MongoDB はデフォルトのメモリ制限である 200 を使用して、各インデックス20 メガバイトをインデックス構築プロセスに割り当てます。メモリ制限に達すると、 MongoDB はビルドを完了するために --dbpath 内の _tmp サブディレクトリに一時ファイルを作成します。

maxIndexBuildMemoryUsageMegabytes パラメーターを使用してメモリ制限を調整します。このパラメータを増やす必要があるのは、単一の createIndexes コマンドで多数の同時インデックス構築を実行する場合や、500 GBより大きいデータセットをインデックスする場合など、まれなケースのみです。

createIndexes コマンドには maxIndexBuildMemoryUsageMegabytes の制限があります。デフォルトの maxNumActiveUserIndexBuilds である 3 を使用する場合、すべての同時インデックスビルドの合計メモリ使用量は、maxIndexBuildMemoryUsageMegabytes の値の最大 3 倍に達します。

ホストマシンで使用可能な空き RAM が限られている場合は、 mongod RAM 使用量を変更する前に、メンテナンス期間をスケジュールしてシステム RAM の合計を増やす必要がある場合があります。

注意

FeatureCompatibilityVersion 4.4 以上が必要です。

レプリカセット全体でインデックス構築を同時に開始するには、レプリカセットまたはシャーディングされたクラスター内の各 mongod は、featureCompatibilityVersion を少なくとも 4.4 に設定する必要があります

レプリカセットまたはシャーディングされたクラスター上のインデックスは、データを保持するすべてのレプリカセット ノードで同時に構築されます。シャーディングされたクラスターの場合、インデックス構築は、インデックスが作成されるコレクションのデータを含むシャードでのみ行われます。プライマリは、インデックスを使用可能とマークする前に、自身を含む最小限のデータを保持する voting ノード(コミットクォーラム)でインデックス構築を完了する必要があります。

重要

データを含む投票ノードにアクセスできなくなり、 commitQuorumがデフォルトのvotingMembersに設定されている場合、そのノードがオンラインに戻るまでインデックスビルドがハングする可能性があります。

ビルド プロセスの概要は以下の通りです。

  1. プライマリは、createIndexes コマンドを受信し、インデックス構築に関連付けられた "startIndexBuild" oplog エントリを直ちに作成します。

  2. セカンダリは、「startIndexBuild」oplog エントリを複製した後、インデックスの構築を開始します。

  3. コレクション内のデータのインデックス作成が終了したら、各ノード間でビルドへのコミットについての ”投票” が行われます。

  4. セカンダリノードは、プライマリが投票の定足数を確認するまで、引き続きインデックスへの新しい書込み操作を処理します。

  5. プライマリで投票の定足数に達すると、重複キーエラーなどキーに関する制約違反がないかどうかがチェックされます。

    • キー制約違反がない場合、プライマリはインデックス構築を完了し、インデックスを使用準備完了としてマークし、関連する「commitIndexBuild」oplog エントリを作成します。

    • キー制約違反がある場合、インデックス構築は失敗します。プライマリはインデックス構築を中止し、関連する「abortIndexBuild」oplog エントリを作成します。

  6. セカンダリは「commitIndexBuild」oplog エントリを複製し、インデックス構築を完了します。

    セカンダリが代わりに「abortIndexBuild」oplog エントリを複製すると、インデックス構築を中止し、構築ジョブを破棄します。

シャーディングされたクラスターの場合、インデックス構築は、インデックスされるコレクションのデータを含むシャードでのみ行われます。

インデックス構築プロセスの詳細については、「インデックス構築プロセス」を参照してください。

デフォルトでは、インデックス構築は "votingMembers" のコミットクォーラム、つまりすべてのデータを保持する投票ノードを使用します。デフォルト以外のコミット クォーラムでインデックス構築を開始するには、 commitQuorumパラメータをcreateIndexesまたはそのシェルヘルパー db.collection.createIndex() および db.collection.createIndexes() に指定します。

進行中の同時インデックス構築に必要なコミットクォーラムを変更するには、setIndexCommitQuorum コマンドを使用します。

警告

ローリングインデックスと複製されたインデックス構築プロセスを同時に実行すると、ビルドの失敗やクラッシュ ループなどの予期しない問題が発生する可能性があるため、避けてください。

注意

ローリングインデックスによるインデックス構築には、一度に最大 1 つのレプリカセットを使用します。セカンダリから始まり、そのノードにスタンドアロンとしてインデックスがビルドされます。ローリングインデックス構築には、少なくとも 1 回のレプリカセット選挙 が必要です。ローリングインデックス構築は、クラスターの回復力が低下するため、ローリングインデックスのページに記載されている要件を満たす場合にのみ使用してください。

コミットクォーラム書込み保証には重要な違いがあります。

  • インデックス構築にはコミットクォーラムを使用します。

  • 書き込み操作には書込み保証が必要です。

クラスタ内の各データ保有ノードは投票ノードです。

コミットクォーラムでは、データを保持する投票権を持つノードの数、または同時インデックス構築をコミットするために準備が必要な投票権を持つノード(プライマリを含む)を指定した後に、プライマリによりコミットが実行されます。

書き込み保証 (write concern) とは、指定された数のインスタンスに書き込み (write) が伝わったことを確認するレベルです。

バージョン 8.0 での変更

コミットクォーラムでは、プライマリがインデックス構築にコミットする前に、インデックス構築を完了する準備が整っていなければならないノードの数を指定します。対照的に、プライマリがインデックス構築にコミットした時に、書き込み保証によって、コマンドが正常に返されるまでにインデックス構築の oplog エントリを複製する必要があるノードの数が指定されます。

以前のリリースでは、プライマリがインデックス構築にコミットした時に、書き込み保証によって、コマンドが正常に返されるまでにインデックス構築を完了する必要があるノードの数が指定されていました。

プライマリまたはセカンダリ mongod"force" : true を使用してクリーンな shutdown を実行するか、インデックス構築中に SIGTERM シグナルを受信し、commitQuorum がデフォルトの votingMembers に設定されている場合、インデックス構築の進捗がディスクに保存されます。mongod は再起動時にインデックス構築を自動的に回復し、保存されたチェックポイントから続行します。

mongod が正常にシャットダウンされずにクラッシュした場合、コミットクォーラムの設定に関係なく、インデックス構築を再開することはできません。mongod がオンラインに戻ると、インデックス構築は最初からやり直されます。

インデックス構築は、保存されたチェックポイントから一度だけ再開できます。同じインデックス構築が進行中に mongod が再起動した場合、ビルドはチェックポイントから再開されず、最初からやり直されます。

mongod は、インデックス構築をリカバリしていますながらスタートアッププロセスを実行できます。

mongod をスタンドアロンとして再起動した場合(つまり、replication.replSetName を除くかコメントアウトするか、--replSetName を省略する)、mongod はインデックス構築を再開できません。手動でdroppedになるまで、ビルドは一時停止状態のままになります。

インデックスビルド中にmongodがシャットダウンすると、インデックスビルドジョブとすべての進行状況が失われます。 mongodを再起動しても、インデックスビルドは再開されません。 インデックスのビルドを再開するには、 createIndex()操作を再発行する必要があります。

MongoDB 5.0以降では、インデックスビルド中にノードが以前の状態にロールバックされた場合、インデックスビルドの進行状況がディスクに保存されます。 ロールバックが完了したときに実行する作業がまだある場合、 mongodは自動的にインデックス構築を回復し、保存されたチェックポイントから続行します。

MongoDB では、進行中のインデックス構築を一時停止してロールバックを実行できます。

  • ロールバックしてもインデックス構築が取り消されない場合、MongoDB はロールバック完了後にインデックス構築を再開します。

  • ロールバックによってインデックス構築が取り消された場合は、ロールバックの完了後に 1 つまたは複数のインデックスを再作成する必要があります。

コレクションのチャンクを含む各シャードに完全に一致するインデックス(インデックスオプションを含む)が存在しない場合、シャーディングされたコレクションれたコレクションにはインデックスの一貫性がありません。通常の操作では一貫性のないインデックスは発生しないはずですが、次のシナリオでは一貫性のないインデックスが発生する可能性があります。

  • unique キー制約を使用してインデックスを作成し、1 つのシャードに重複 document を含むチャンクが含まれている場合。このような場合、インデックスの作成操作は、重複のないシャードでは成功するものの、重複のあるシャードでは成功しない可能性があります。

  • 複数のシャードにわたってインデックスをローリング処理で作成する場合(複数のシャードにわたって手作業でインデックスを 1 つずつビルドする場合)、関連付けられたシャードのインデックス作成に失敗するか、異なる仕様で誤ったインデックスをビルドする場合のいずれかになります。

コンフィギュレーションサーバーのプライマリは、シャーディングされたコレクションのシャード間でのインデックスの不整合を定期的にチェックします。 これらの定期的チェックを構成するには、 enableShardedIndexConsistencyCheckshardedIndexConsistencyCheckIntervalMSを参照してください。

コマンドserverStatusは、構成サーバーのプライマリで実行された場合にインデックスの不整合を報告するフィールド shardedIndexConsistency を返します。

シャーディングされたコレクションに一貫性のないインデックスがないかどうかを確認するには、「シャード間で一貫性のないインデックスを検索する」を参照してください。

To see the status of an index build operation, you can use the db.currentOp() method in mongosh. To filter the current operations for index creation operations, see Active Indexing Operations for an example.

msg フィールドには、インデックス構築プロセスの現在のステージにおける完了割合が含まれています。

インデックスが構築されている間、進捗状況は MongoDB ログに記録されます。インデックス構築が停止して再開されると、次のようなフィールドを含むログメッセージが表示されます。

"msg":"Index build: wrote resumable state to disk",
"msg":"Found index from unfinished build",

進行中のインデックス構築を終了するには、 dropIndexes コマンドまたはそのシェルヘルパー dropIndex() または dropIndexes() を使用します。詳細については、「進行中のインデックス構築の停止」を参照してください。

レプリカセットまたはシャーディングされたクラスターで進行中のインデックス構築を終了するためにkillOp は使用しないでください。

次の表は、インデックス構築プロセスの各段階について説明しています。

ステージ
説明

ロック

mongodは、インデックス作成されるコレクションに対して排他Xロックを取得します。 これにより、コレクションを対象とする複製された書込み (write) 操作やメタデータ コマンドの適用など、コレクションに対するすべての読み取り操作と書込み (write) 操作がブロックされます。 The mongod does not yield this lock.

初期化

mongodは、この初期状態で次の 3 つのデータ構造を作成します。

  • 初期インデックスのメタデータエントリ。

  • ビルドプロセス中にインデックスされるコレクションへの書込みによって生成されたキーを格納する一時テーブル (サイド書込みテーブル)。

  • キー生成エラーを引き起こす可能性のあるすべてのドキュメントの一時テーブル (制約違反テーブル)。ドキュメントのインデックス フィールドに無効なキーがある場合、キー生成エラーが発生します。たとえば、ユニークインデックスを構築するときにフィールド値が重複しているドキュメント、または 2dsphere インデックスを構築するときに GeoJSON オブジェクト が不正な場合などです。

ロック

mongodは、排他的X IXロックを意向排他 ロックにダウングレードします。 mongodは、読み取り操作と書込み(write)操作をインターリーブするためにこのロックを定期的にロックします。

コレクションのスキャン

コレクション内の各ドキュメントに対して、 mongodはそのドキュメントのキーを生成し、そのキーを外部ソーターにダンプします。

コレクションスキャン中にmongodがキーを生成中にキー生成エラーが発生した場合、後で処理できるように制約違反テーブルに保存されます。

mongodがキーの生成中に他のエラーに発生した場合、ビルドはエラーで失敗します。

mongodがコレクションスキャンを完了すると、ソートされたキーをインデックスにダンプします。

プロセスサイド書込みテーブル

mongodは、先入れ先出しの優先順位を使用してサイド書き込みテーブルを空にします。

mongodがサイド書込みテーブルでキーを処理中にキー生成エラーを発生した場合、後で処理できるように制約違反テーブルに保存されます。

mongodがキーを処理中に他のエラーが発生した場合、ビルドはエラーで失敗します。

mongod は、構築プロセス中にコレクションに書き込まれるドキュメントごとに、そのドキュメントのキーを生成し、後で処理できるようにサイド書込みテーブルに格納します。mongod はスナップショット システムを使用して、処理するキーの数に制限を設定します。

投票とコミットクォーラムの待機

レプリカセットの一部ではないmongodは、このステージをスキップします。

mongodは、インデックスをコミットするためにプライマリに「投票」を送信します。 具体的には、プライマリ上の内部複製コレクションに「投票」を書込みます。

mongodプライマリの場合、コミットクォーラムが投票(デフォルトではすべての投票データを保持するノード)に達するまで待機してから、インデックス ビルド プロセスを続行します。

mongodセカンダリの場合、"commitIndexBuild" または "abortIndexBuild" oplog エントリのいずれかが複製されるまで待機します。

  • mongodが "CommitIndexBuild" oplog エントリを複製すると、サイド書込みテーブルの処理が完了し、インデックス構築プロセスの次の段階に進みます。

  • mongod が "abortIndexBuild" oplog エントリを複製すると、インデックス構築が中止され、構築ジョブが破棄されます。

コミットクォーラムを待っている間、mongod は、インデックス付けされるコレクションへの書込み (write) 操作から生成された追加のキーをサイド書込みテーブルに追加し、定期的にテーブルを空にします。

ロック

mongodは、コレクションの意向排他IXロックを共有Sロックにアップグレードします。 これにより、コレクションを対象とする複製された書込み (write) 操作やメタデータ コマンドの適用など、コレクションへのすべての書込み (write) 操作がブロックされます。

一時サイド書き込みテーブルの処理の完了

mongod は、一時テーブル内の残りのレコードの処理を続行します。mongod はこの段階でレプリケーションを一時停止する可能性があります。

mongodがサイド書込みテーブルでキーを処理中にキー生成エラーを発生した場合、後で処理できるように制約違反テーブルに保存されます。

mongodがキーを処理中に他のエラーが発生した場合、ビルドはエラーで失敗します。

ロック

mongod は、コレクションの共有 S ロックをコレクションの排他的 X ロックにアップグレードします。これにより、コレクションを対象とする複製された書込み (write) 操作やメタデータ コマンドの適用など、コレクションに対するすべての読み取り操作と書込み (write) 操作がブロックされます。mongod はこのロックを停止しません。

サイド書き込みテーブルの削除

mongodは、削除する前にサイド書込みテーブル内の残りの操作を適用します。

mongodがサイド書込みテーブルでキーを処理中にキー生成エラーを発生した場合、後で処理できるように制約違反テーブルに保存されます。

mongodがキーを処理中に他のエラーが発生した場合、ビルドはエラーで失敗します。

この時点で、インデックスにはコレクションに書き込まれたすべてのデータが含まれます。

プロセス制約違反テーブル

mongodプライマリの場合、先入れ先出しの優先順位を使用して制約違反テーブルを空にします。

  • 制約違反テーブルのどのキーもキー生成エラーを生成しない場合、またはテーブルが空の場合、 mongodはテーブルを削除し、"commitIndexBuild" oplog エントリを作成します。 セカンダリは、oplog エントリを複製した後、関連するインデックスのビルドを完了できます。

  • 制約違反テーブル内のいずれかのキーでもキー生成エラーが発生する場合、 mongodはビルドを中止し、エラーをスローします。 mongodは、関連する "abortIndexBuild" oplog エントリを作成し、セカンダリがインデックス構築ジョブを中止して破棄する必要があることを示します。

mongodセカンダリの場合、制約違反テーブルが削除されます。 "commitOplogEntry" oplog エントリを作成する前に、プライマリが制約違反テーブルを正常に空にする必要があるため、セカンダリは違反が存在しないことを前提とできます。

インデックスを準備完了としてマークします

mongodはインデックスを使用可能としてマークするようにインデックス メタデータを更新します。

ロック

mongodはコレクションのXロックを解放します。