クエリパラメータdebug=true
により、期待されるすべてのデータを返さないか、予期しないデータを返す、stale=false
を使用したクエリをデバッグすることができます。クライアントでmemcachedのOBSERVEコマンドによってブロックが解除されたすぐ後に、stale=false
クエリを発行したときに特に便利です。この問題が発生した例はMB-7161にあります。
ここでは、(1024の代わりに)16のvbucketsと2つのノードのみがある単純なシナリオでこの種の問題のデバッグの仕方の例を示します。(couchstore gitプロジェクトからの)couchdb_dump
とcouchdb_info
のツールを使用すると、この種類の問題を解析する助けとなります(install/bin
ディレクトリの下で有効です)。
debug=true
を使用したビューへ問い合わせをすると、ビューの応答の中にdebug_info
という名前の拡張フィールドが追加されます。このフィールドには、(たとえば停止/タイムアウトしたノードのようなエラーが起こらなかった場合)クラスタ内のノードごとに1つのエントリがあります。例
shell> curl -s 'http://localhost:9500/default/_design/test/_view/view1?stale=false&limit=5&debug=true' | json_xs { "debug_info" : { "local" : { "main_group" : { "passive_partitions" : [], "wanted_partitions" : [ 0, 1, 2, 3, 4, 5, 6, 7 ], "wanted_seqs" : { "0002" : 62500, "0001" : 62500, "0006" : 62500, "0005" : 62500, "0004" : 62500, "0000" : 62500, "0007" : 62500, "0003" : 62500 }, "indexable_seqs" : { "0002" : 62500, "0001" : 62500, "0006" : 62500, "0005" : 62500, "0004" : 62500, "0000" : 62500, "0007" : 62500, "0003" : 62500 }, "cleanup_partitions" : [], "stats" : { "update_history" : [ { "deleted_ids" : 0, "inserted_kvs" :00, "inserted_ids" :00, "deleted_kvs" : 0, "cleanup_kv_count" : 0, "blocked_time" : 0.000258, "indexing_time" : 103.222201 } ], "updater_cleanups" : 0, "compaction_history" : [], "full_updates" : 1, "accesses" : 1, "cleanups" : 0, "compactions" : 0, "partial_updates" : 0, "stopped_updates" : 0, "cleanup_history" : [], "update_errors" : 0, "cleanup_stops" : 0 }, "active_partitions" : [ 0, 1, 2, 3, 4, 5, 6, 7 ], "pending_transition" : null, "unindexeable_seqs" : {}, "replica_partitions" : [ 8, 9, 10, 11, 12, 13, 14, 15 ], "original_active_partitions" : [ 0, 1, 2, 3, 4, 5, 6, 7 ], "original_passive_partitions" : [], "replicas_on_transfer" : [] } }, "http://10.17.30.98:9501/_view_merge/" : { "main_group" : { "passive_partitions" : [], "wanted_partitions" : [ 8, 9, 10, 11, 12, 13, 14, 15 ], "wanted_seqs" : { "0008" : 62500, "0009" : 62500, "0011" : 62500, "0012" : 62500, "0015" : 62500, "0013" : 62500, "0014" : 62500, "0010" : 62500 }, "indexable_seqs" : { "0008" : 62500, "0009" : 62500, "0011" : 62500, "0012" : 62500, "0015" : 62500, "0013" : 62500, "0014" : 62500, "0010" : 62500 }, "cleanup_partitions" : [], "stats" : { "update_history" : [ { "deleted_ids" : 0, "inserted_kvs" :00, "inserted_ids" :00, "deleted_kvs" : 0, "cleanup_kv_count" : 0, "blocked_time" : 0.000356, "indexing_time" : 103.651148 } ], "updater_cleanups" : 0, "compaction_history" : [], "full_updates" : 1, "accesses" : 1, "cleanups" : 0, "compactions" : 0, "partial_updates" : 0, "stopped_updates" : 0, "cleanup_history" : [], "update_errors" : 0, "cleanup_stops" : 0 }, "active_partitions" : [ 8, 9, 10, 11, 12, 13, 14, 15 ], "pending_transition" : null, "unindexeable_seqs" : {}, "replica_partitions" : [ 0, 1, 2, 3, 4, 5, 6, 7 ], "original_active_partitions" : [ 8, 9, 10, 11, 12, 13, 14, 15 ], "original_passive_partitions" : [], "replicas_on_transfer" : [] } } }, "total_rows" : 1000000, "rows" : [ { "value" : { "ratio" : 1.8, "type" : "warrior", "category" : "orc" }, "id" : "0000014", "node" : "http://10.17.30.98:9501/_view_merge/", "partition" : 14, "key" : 1 }, { "value" : { "ratio" : 1.8, "type" : "warrior", "category" : "orc" }, "id" : "0000017", "node" : "local", "partition" : 1, "key" : 1 }, { "value" : { "ratio" : 1.8, "type" : "priest", "category" : "human" }, "id" : "0000053", "node" : "local", "partition" : 5, "key" : 1 }, { "value" : { "ratio" : 1.8, "type" : "priest", "category" : "orc" }, "id" : "0000095", "node" : "http://10.17.30.98:9501/_view_merge/", "partition" : 15, "key" : 1 }, { "value" : { "ratio" : 1.8, "type" : "warrior", "category" : "elf" }, "id" : "0000151", "node" : "local", "partition" : 7, "key" : 1 } ] }
各ノードでは、いくつかのデータが欠如しているようなstale=false
クエリのデバッグの時に特に興味深い2つのフィールドがあります:
wanted_seqs
- このフィールドはキーがvbucket IDで、値がvbucketのデータベースのシーケンス番号であるオブジェクト(辞書)の値を持っています。(シーケンス番号の説明のために「クエリ応答にデータがない、もしくは間違い(潜在的なサーバの問題による)」を参照してください)。このフィールドにより、各vbucketデータベースファイルの(対応するノードでの)クエリがサーバに届いたときのシーケンス番号を知ることができます(これらのvbucketすべてはアクティブvbuckets
となります)。
indexable_seqs
- このフィールドはキーがvbucket IDで、値がvbucketのデータベースのシーケンス番号であるオブジェクト(辞書)の値を持っています。このフィールドにより、各アクティブvbucketデータベースにとって、処理されている/インデックされているドキュメントをインデックスが保持できるシーケンスの最大値を知ることができます。(各vbucketデータベースのシーケンス番号は1つのそしてただ1つのドキュメントに関連付けられていていることに注意してください。)
stale=false
を使用した問い合わせにより、indexable_seqs
内のすべてのシーケンスがwanted_seqs
内のシーケンスよりも多いか、等しくなる必要があります。
- そうでなければ、stale=false
オプションは壊れる場合があること考慮するべきです。その場面の背後で、各ノード上で起こっていることは、クエリ要求が届いたとき、
wanted_seqs
の値が(現在のシーケンス番号に対するアクティブなvbucketデータベースに問い合わせることで)計算され、そしてシーケンスが(インデックスに格納されている)indexable_seqs
内の対応するエントリよりも多い場合には、クライアントをブロックし、そのインデクサがインデックの更新を開始し、インデクサがインデックスの更新を完了したときにクライアントのブロックを解除し、そして最後にサーバがクライアントに行のストリーミングを開始します。- この時点では、indexable_seqs
内のすべてのシーケンスは、wanted_sequences
内の対応するシーケンスよりも必ず大きいか、等しくなり、そうでなければstale=false
の実装が壊れています。