Search:

Search all manuals
Search this manual
Manual
Couchbase Server マニュアル 2.0
Community Wiki and Resources
Couchbase Server 2.0をダウンロード
Couchbase 開発者ガイド 2.0
クライアントライブラリ
Couchbase Server フォーラム
Additional Resources
Community Wiki
Community Forums
Couchbase SDKs
Parent Section
D ビューのトラブルシューティング(技術的背景)
Chapter Sections
Chapters

D.6. クエリ応答にデータがない、もしくは間違い(潜在的なサーバの問題による)

時々、特に開発ビルドのリリース間で、Couchbase Serverのいくつかのコンポーネントに問題があるため、結果が失われるという可能性があります。このセクションでは、どのコンポーネントか、もしくはどのコンポーネントが失敗していないかを識別するためにデバッグする方法について説明します。

先に進む前に、ファイルシステム内の1ファイルに正確に対応した(couchstoreコンポーネントによって作成された)CouchDBデータベースによって、各vbucketが物理的に表現されているということに言及する必要があり、(たとえば、簡単にするために)16 vbucketsのみを使用した4ノードとレプリカなしの開発環境の例を以下に示します。

shell> tree ns_server/couch/0/
ns_server/couch/0/
 ???
_replicator.couch.1
 ???
_users.couch.1
 ??? default
     ??? 0.couch.1
     ??? 1.couch.1
     ??? 2.couch.1
     ??? 3.couch.1
     ??? master.couch.1
     ??? stats.json

 1 directory, 8 files

shell> tree ns_server/couch/1/
ns_server/couch/1/
 ???
_replicator.couch.1
 ???
_users.couch.1
 ??? default
     ??? 4.couch.1
     ??? 5.couch.1
     ??? 6.couch.1
     ??? 7.couch.1
     ??? master.couch.1
     ??? stats.json
     ??? stats.json.old

 1 directory, 9 files

shell> tree ns_server/couch/2/
ns_server/couch/2/
 ???
_replicator.couch.1
 ???
_users.couch.1
 ??? default
     ??? 10.couch.1
     ??? 11.couch.1
     ??? 8.couch.1
     ??? 9.couch.1
     ??? master.couch.1
     ??? stats.json
     ??? stats.json.old

 1 directory, 9 files

shell> tree ns_server/couch/3/
ns_server/couch/3/
 ???
_replicator.couch.1
 ???
_users.couch.1
 ??? default
     ??? 12.couch.1
     ??? 13.couch.1
     ??? 14.couch.1
     ??? 15.couch.1
     ??? master.couch.1
     ??? stats.json
     ??? stats.json.old

 1 directory, 9 files

この特定の例では(./cluster_connect -n 4 -r 0を実行した)レプリカは無効なので、各ノードはその責任範囲であるvbuckets(アクティブvbuckets)のデータベースファイルのみを持っています。各データベースファイル名の数字の接尾辞は、データベースファイルが作成されたときに1から開始され、vbucketがコンパクションされるたびに1ずつ増加します。例えば、./cluster_connect -n 4 -r 1を実行するなどして、レプリケーションが有効になっている場合、各ノードは責任範囲内のvbucket(アクティブvbuckets)のためと、いくつかのレプリカvbucketsのためのvbucketデータベースファイルを持っています:

shell> tree ns_server/couch/0/

ns_server/couch/0/
 ???
_replicator.couch.1
 ???
_users.couch.1
 ??? default
     ??? 0.couch.1
     ??? 1.couch.1
     ??? 12.couch.1
     ??? 2.couch.1
     ??? 3.couch.1
     ??? 4.couch.1
     ??? 5.couch.1
     ??? 8.couch.1
     ??? master.couch.1
     ??? stats.json

 1 directory, 12 files

shell> tree ns_server/couch/1/

ns_server/couch/1/
 ???
_replicator.couch.1
 ???
_users.couch.1
 ??? default
     ??? 0.couch.1
     ??? 1.couch.1
     ??? 13.couch.1
     ??? 4.couch.1
     ??? 5.couch.1
     ??? 6.couch.1
     ??? 7.couch.1
     ??? 9.couch.1
     ??? master.couch.1
     ??? stats.json

 1 directory, 12 files

shell> tree ns_server/couch/2/

ns_server/couch/2/
 ???
_replicator.couch.1
 ???
_users.couch.1
 ??? default
     ??? 10.couch.1
     ??? 11.couch.1
     ??? 14.couch.1
     ??? 15.couch.1
     ??? 2.couch.1
     ??? 6.couch.1
     ??? 8.couch.1
     ??? 9.couch.1
     ??? master.couch.1
     ??? stats.json

 1 directory, 12 files

shell> tree ns_server/couch/3/
ns_server/couch/3/
 ???
_replicator.couch.1
 ???
_users.couch.1
 ??? default
     ??? 10.couch.1
     ??? 11.couch.1
     ??? 12.couch.1
     ??? 13.couch.1
     ??? 14.couch.1
     ??? 15.couch.1
     ??? 3.couch.1
     ??? 7.couch.1
     ??? master.couch.1
     ??? stats.json

 1 directory, 12 files

次のURLのクエリを実行することにより、どのvbucketが各ノード上でアクティブかがわかります:

shell> curl -s http://localhost:9000/pools/default/buckets |
  json_xs
 [
    {
       "quota" :
{
          "rawRAM" : 268435456,
          "ram"
: 1073741824
       },
       "localRandomKeyUri" : "/pools/default/buckets/default/localRandomKey",
       "bucketCapabilitiesVer" : "",
       "authType"
: "sasl",
       "uuid" :
  "89dd5c64504f4a9414a2d3bcf9630d15",
       "replicaNumber" : 1,
       "vBucketServerMap" : {
          "vBucketMap" : [
             [
                0,
                1
             ],
             [
                0,
                1
             ],
             [
                0,
                2
             ],
             [
                0,
                3
             ],
             [
                1,
                0
             ],
             [
                1,
                0
             ],
             [
                1,
                2
             ],
             [
                1,
                3
             ],
             [
                2,
                0
             ],
             [
                2,
                1
             ],
             [
                2,
                3
             ],
             [
                2,
                3
             ],
             [
                3,
                0
             ],
             [
                3,
                1
             ],
             [
                3,
                2
             ],
             [
                3,
                2
             ]
          ],
          "numReplicas" : 1,
          "hashAlgorithm" : "CRC",
          "serverList" : [
             "192.168.1.81:12000",
             "192.168.1.82:12002",
             "192.168.1.83:12004",
             "192.168.1.84:12006"
          ]
       },

(....)
 ]

検査のためのフィールドにはvBucketServerMapという名前が付けられており、そしてそれはvBucketMapserverListという名前の2つの重要なサブフィールドを含み、どのノードがどのvbuckets(アクティブvbuckets)の責任範囲かを調べるために使用されます。

これらの2つのフィールドを確認すると、次のアクティブおよびレプリカvbucketをノードへマッピングすることができます。

vBucketMapの値は2つの要素の配列の配列です。各サブ配列がvbucketに対応しているので、最初のものはvbucketの0、次のものはvbucketの1、など、最後のものはvbucketの15に関連しています。各サブ配列要素は、serverList配列へのインデックス(0から始まる)です。各サブ配列の最初の要素は、どのノードがアクティブとしてマークされたvbucketに対応しているかをを示し、二番目の要素がどのサーバがレプリカとしてマークされたvbucketを持っているを示しています。

レプリケーション因子が1よりも大きい場合(N>1)には、各サブ配列は、N+1の要素をもち、最初の要素は、常にvbuketをアクティブとしているサーバ/ノードのインデックスとなり、残りの要素は1番目、2番目、3番目など、vbucketのレプリカを持っているサーバのインデックスとなります。

どのvbucketsが各ノードでアクティブになっているか知った後、アクティブなvbucketデータベースのファイルを分析するため、couch_dbinfocouch_dbdumpのようないくつかのツールを使用することができます。それらのツールを見ていく前に、まずデータベースのシーケンス番号が何であるかを調べましょう。

CouchDBのデータベース(それぞれがvbucketに対応していることを忘れないでください)が作成されると、そのupdate_seq(更新シーケンス番号)は0となります。ドキュメントが作成、更新または削除されるとき、その現在のシーケンス番号が1ずつインクリメントされます。だから、次のアクションのシーケンスのすべてが、5の最終シーケンス番号になります:

  1. ドキュメントdoc1を作成し、ドキュメントdoc2を作成し、ドキュメントdoc3を作成し、ドキュメントdoc4を作成し、ドキュメントdoc5を作成する

  2. ドキュメントdoc1を作成し、ドキュメントdoc1を更新し、ドキュメントdoc1を更新し、ドキュメントdoc1を更新し、ドキュメントdoc1を削除する

  3. ドキュメントdoc1を作成し、ドキュメントdoc1を削除し、ドキュメントdoc2を作成し、ドキュメントdoc2を更新し、ドキュメントdoc2を更新する

  4. ドキュメントdoc1を作成し、ドキュメントdoc2を作成し、ドキュメントdoc3を作成し、ドキュメントdoc4を作成し、ドキュメントdoc2を更新する

  5. などなど

他の情報の中で、couch_dbinfoコマンドラインツールを使用して、vbucketデータベースのファイルの現在のupdate_seqを見ることができ、たとえば、最初のノードでアクティブなvbucketの0を使用した例は次の通りです:

shell> ./install/bin/couch_dbinfo ns_server/couch/0/default/0.couch.1
 DB Info
  (ns_server/couch/0/default/0.couch.1)
    file format version: 10
    update_seq: 31250
    doc count: 31250
    deleted doc count: 0
    data size: 3.76 MB
    B-tree size: 1.66 MB
    total disk size: 5.48 MB

vbucketデータベース内のすべてのドキュメントを更新した後、update_seqは倍増します:

shell> ./install/bin/couch_dbinfo ns_server/couch/0/default/0.couch.1
DB Info
 (ns_server/couch/0/default/0.couch.1)
   file format version: 10
   update_seq: 62500
   doc count: 31250
   deleted doc count: 0
   data size: 3.76 MB
   B-tree size: 1.75 MB
   total disk size: 10.50 MB

重要なのは、明白ではない場合、各vbucketデータベースのシーケンス番号に、1つそしてただ1つのドキュメントIDが関連付けられているということです。いつでも、ドキュメントIDに関連付けられている1つの更新シーケンス番号があり、常に最新状態となっています。couch_dbdumpコマンドラインツールを使用してこのドキュメントIDを確認することができます。ID doc1というドキュメントとID doc2というドキュメントの2つのドキュメントだけをもつ、以下の例を見てください。

shell> ./install/bin/couch_dbdump ns_server/couch/0/default/0.couch.1
Doc seq: 1
     id: doc1
     rev: 1
     content_meta: 0
     cas: 130763975746, expiry: 0, flags: 0
     data: {"value": 1}
Total docs: 1

空のvbucket 0 データベースで、{"value": 1}のJSON値を持っているIDdoc1のドキュメントを作成します。このドキュメントは現在更新シーケンス番号1に関連付けられています。次に{"value": 2}のJSONの値を持っているID *doc2* の別のドキュメントを作成すると、couch_dbdumpの出力は次の通りです:

shell> ./install/bin/couch_dbdump ns_server/couch/0/default/0.couch.1
Doc seq: 1
     id: doc1
     rev: 1
     content_meta: 0
     cas: 130763975746, expiry: 0, flags: 0
     data: {"value": 1}
Doc seq: 2
     id: doc2
     rev: 1
     content_meta: 0
     cas: 176314689876, expiry: 0, flags: 0
     data: {"value": 2}
Total docs: 2

ドキュメントdoc2は、vbucket 0 データベースの更新シーケンス番号2に関連付けられています。次に{"value": 1111}の新しいJSONの値でドキュメントdoc1を更新すると、couch_dbdumpは次を示します。

shell> ./install/bin/couch_dbdump ns_server/couch/0/default/0.couch.1
Doc seq: 2
     id: doc2
     rev: 1
     content_meta: 0
     cas: 176314689876, expiry: 0, flags: 0
     data: {"value": 2}
Doc seq: 3
     id: doc1
     rev: 2
     content_meta: 0
     cas: 201537725466, expiry: 0, flags: 0
     data: {"value": 1111}

Total docs: 2

ドキュメントdoc1は現在、更新シーケンス番号3に関連付けられています。更新がドキュメントに対する最新の操作となるため、もはやシーケンス番号1には関連付けられていないことに注意してください。(3つの操作のみ可能であることを忘れないでください:作成、更新、または削除)同様にデータベースはもはやシーケンス番号1のレコードがありません。この後、{"value": 2222}のJSON値でドキュメントdoc2をアップデートすると、couch_dbdumpから以下のような出力を得ます:

shell> ./install/bin/couch_dbdump ns_server/couch/0/default/0.couch.1
Doc seq: 3
     id: doc1
     rev: 2
     content_meta: 0
     cas: 201537725466, expiry: 0, flags: 0
     data: {"value": 1111}
Doc seq: 4
     id: doc2
     rev: 2
     content_meta: 0
     cas: 213993873979, expiry: 0, flags:   0
     data: {"value": 2222}

Total docs: 2

ドキュメントdoc2は今シーケンス番号4に関連付けられていて、データベースファイルにはもはやシーケンス番号2のレコードがありません。最後に、ドキュメントdoc1を削除すると、次のような情報が得られます:

shell> ./install/bin/couch_dbdump ns_server/couch/0/default/0.couch.1
Doc seq: 4
     id: doc2
     rev: 2
     content_meta: 0
     cas: 213993873979, expiry: 0, flags: 0
     data: {"value": 2222}
Doc seq: 5
     id: doc1
     rev: 3
     content_meta: 3
     cas: 201537725467, expiry: 0, flags: 0
     doc deleted
     could not read document body: document not found

Total docs: 2

ドキュメントの削除は実際にはデータベースファイルからドキュメントを削除せず、その代わりに、そのドキュメントが削除されたというフラグをつけ、そのJSON(またはバイナリ)の値を削除するということに注意してください。ドキュメントdoc1は今では、シーケンス番号5に関連付けられており、以前のシーケンス番号3に関連付けられたレコードはvbucket 0 データベースファイルから削除されています。これによって例えば、削除操作に関連付けられた更新シーケンス番号がないので、インデックスはドキュメントが削除されたかどうか知るための方法を持っていませんが、削除されたドキュメントのmap関数で以前に出力されてたすべてのキーバリューペアが削除されなければならないことをインデックスは知ることができます。

シーケンス番号やドキュメント操作の詳細によって、インデックスはCouchbase Server(そして同様にApache CouchDB)内で増分更新することができます。

Couchbase Serverでは、インデックスは各vbucket データベースで参照される最新のupdate_seqをヘッダ(状態)内に格納しています。簡単に言えば、インデックスの構築/更新が完了したかどうかは、各vbucketデータベースが処理するヘッダ内の最新のupdate_seqに格納します。vbucket データベースは状態もインデックス内に持っており、その状態はサーバ内のvbucket状態と必ずしも一致していません。このwikiページの目的としては、インデックスヘッダ内に現在格納されているアクティブなvbucketのupdate_seqが対応するvbucketデータベースの現在のupdate_seqよりも小さい場合のみ、stale=falseを使用したビューのリクエストはブロックされるということを言及することだけが重要で、 - もし少なくとも1つのアクティブなvbucketでこれがtrueであれば、(まだ実行中でない場合)インデックス更新はすぐさまスケジュールされ、完了したとき、リクエストをアンブロックします。もし他の状態 (passive, cleanup, replica) のインデックス内のvbucketsのupdate_seqが対応するvbucketデータベースの現在のupdate_seqよりも小さければ、stale=falseのリクエストはブロックされません。 - 理由としては、クエリはアクティブvbucketsに存在するドキュメントから生成される行だけ参照しているということです。

次のURLでクエリを実行することによって、インデックス内のvbucketsの状態とインデックス内のupdate_seqsを参照できます(単純化のために、16 vbucketsのみの例):

shell> curl -s 'http://localhost:9500/_set_view/default/_design/dev_test2/_info' | json_xs
{
   "unindexable_partitions" : {},
   "passive_partitions" : [],
   "compact_running" : false,
   "cleanup_partitions" : [],
   "replica_group_info" : {
      "unindexable_partitions" : {},
      "passive_partitions" : [
         4,
         5,
         8,
         12
      ],
      "compact_running" : false,
      "cleanup_partitions" : [],
      "active_partitions" : [],
      "pending_transition" : null,
      "db_set_message_queue_len" : 0,
      "out_of_sync_db_set_partitions" : false,
      "expected_partition_seqs" : {
         "8" : 62500,
         "4" : 62500,
         "12" : 62500,
         "5" : 62500
      },
      "updater_running" : false,
      "partition_seqs" : {
         "8" : 62500,
         "4" : 62500,
         "12" : 62500,
         "5" : 62500
      },
      "stats" : {
         "update_history" : [
            {
               "deleted_ids" : 0,
               "inserted_kvs" : 38382,
               "inserted_ids" : 12794,
               "deleted_kvs" : 38382,
               "cleanup_kv_count" : 0,
               "blocked_time" : 1.5e-05,
               "indexing_time" : 3.861918
            }
         ],
         "updater_cleanups" : 0,
         "compaction_history" : [
            {
               "cleanup_kv_count" : 0,
               "duration" : 1.955801
            },
            {
               "cleanup_kv_count" : 0,
               "duration" : 2.443478
            },
            {
               "cleanup_kv_count" : 0,
               "duration" : 4.956397
            },
            {
               "cleanup_kv_count" : 0,
               "duration" : 9.522231
            }
         ],
         "full_updates" : 1,
         "waiting_clients" : 0,
         "compactions" : 4,
         "cleanups" : 0,
         "partial_updates" : 0,
         "stopped_updates" : 0,
         "cleanup_history" : [],
         "cleanup_interruptions" : 0
      },
      "initial_build" : false,
      "update_seqs" : {
         "8" : 62500,
         "4" : 62500,
         "12" : 62500,
         "5" : 62500
      },
      "partition_seqs_up_to_date" : true,
      "updater_state" : "not_running",
      "data_size" : 5740951,
      "cleanup_running" : false,
      "signature" : "440b0b3ded9d68abb559d58b9fda3e0a",
      "max_number_partitions" : 16,
      "disk_size" : 5742779
   },
   "active_partitions" : [
      0,
      1,
      2,
      3
   ],
   "pending_transition" : null,
   "db_set_message_queue_len" : 0,
   "out_of_sync_db_set_partitions" : false,
   "replicas_on_transfer" : [],
   "expected_partition_seqs" : {
      "1" : 62500,
      "3" : 62500,
      "0" : 62500,
      "2" : 62500
   },
   "updater_running" : false,
   "partition_seqs" : {
      "1" : 62500,
      "3" : 62500,
      "0" : 62500,
      "2" : 62500
   },
   "stats" : {
      "update_history" : [],
      "updater_cleanups" : 0,
      "compaction_history" : [],
      "full_updates" : 0,
      "waiting_clients" : 0,
      "compactions" : 0,
      "cleanups" : 0,
      "partial_updates" : 0,
      "stopped_updates" : 0,
      "cleanup_history" : [],
      "cleanup_interruptions" : 0
   },
   "initial_build" :   false,
   "replica_partitions" : [
      4,
      5,
      8,
      12
   ],
   "update_seqs" : {
      "1" : 31250,
      "3" : 31250,
      "0" : 31250,
      "2" : 31250
   },
   "partition_seqs_up_to_date" : true,
   "updater_state" :   "not_running",
   "data_size" : 5717080,
   "cleanup_running" : false,
   "signature" :   "440b0b3ded9d68abb559d58b9fda3e0a",
   "max_number_partitions" : 16,
   "disk_size" : 5726395
}

サーバの問題を診断するのに有用ないくつかのフィールドが出力されます。フィールドreplica_group_infoは、このwikiの目的を無視し(フェイルオーバ中だけ有用となるでしょう)、含まれている情報はトップレベルの情報と類似しており、メインで主要なインデックスのためのもので、安定状態の間やリバランスの間に注意するべきものです。

トップレベルのフィールドのいくつかとその意味は次のとおりです:

このURLによって得られる情報を使用して(ノード単位であることを忘れないでください)、couch_dbinfocouch_dbdumpツールと一緒に(アクティブなvbucketデータベースのファイルすべてに対して)、vbucketの状態やインデックスされたupdate_seqsを確認することで、どこに(どのコンポーネントに)問題があるのかデバッグすることができます。たとえば、最新のデータ/更新/削除処理でインデックスされていないインデックスがあるかどうか、memcached/ep-engineレイヤーがディスクへのデータ永続化/更新がしているかどうか、couchstore(データベースファイルに書き込むコンポーネント)でデータベースファイルにデータを書き込まない、もしくは間違ったデータを書き込むような問題がないかどうか、を調べるのに役に立ちます。

これらのツールやURL/_set_view/bucketname/_design/ddocid/_infoからの情報を使用して、どのコンポーネントがおかしな振る舞いをしているのかを調べることがとても重要であるという例はhttp://www.couchbase.com/issues/browse/MB-5534にあります。このケースではトミーは、問題がep-engineにあったことを識別することができました。