読者です 読者をやめる 読者になる 読者になる

256bitの殺人メニュー

インフラエンジニアだったソリューションアーキテクトなくわののブログ。こちらのBlogは個人の意見となっていて会社とは全く関係ありません。お約束です。[twitter:@kuwa_tw]めんどくさがりが重い腰を上げて何かをアウトプットすることにどれほどの意味があるのかを試してみたいブログでもある。

MongoDBでChunkのMigrationが進行中か確認したい場合

MongoDBのAutoBalancingって便利ですよね。

便利というか、手動Balancingが即時全体反映じゃないので、AutoBalancing使わざるを得ない理由もありますが(; ・`д・´)

というわけで、今Shard間でChunkのMigration(以下moveChunk)が走っていないか確認する方法です。
小ネタ注意報。

configデータベース

mongocに入っているconfigデータベースには各種Shardingに関する情報が入っています。
これらのCollectionを見ることで現在のShardingの情報は大体わかります。

スキーマの概要はここ

changelogコレクション

Splitとか、moveChunkが走っているかを見たいのであれば、changelogコレクションを見ましょう。
ここにSplitや、moveChunk等のイベントの進行状況がわかるようになっています。
デフォルトでは10MのCappedCollectionです。

見方
$ /usr/local/mongodb2_1/bin/mongo # mongocにつなぐ
> use config
> db.changelog.find()
(snip)
{ "_id" : "mongotest-25-2011-10-17T23:35:25-118", "server" : "mongotest-25", "clientAddr" : "192.168.0.150:56639", "time" : ISODate("2011-10-17T23:35:25.635Z"), "what" : "moveChunk.from", "ns" : "testdatabase.testcollection", "details" : { "min" : { "_id" : "742e4aeaf3f1806b" }, "max" : { "_id" : "74fa5d10c4e68473" }, "step1" : 0, "step2" : 7, "note" : "aborted" } }
{ "_id" : "mongotest-25-2011-10-17T23:35:25-119", "server" : "mongotest-25", "clientAddr" : "192.168.0.150:56639", "time" : ISODate("2011-10-17T23:35:25.666Z"), "what" : "split", "ns" : "testdatabase.testcollection", "details" : { "before" : { "min" : { "_id" : "742e4aeaf3f1806b" }, "max" : { "_id" : "74fa5d10c4e68473" }, "lastmod" : { "t" : 203000, "i" : 1 } }, "left" : { "min" : { "_id" : "742e4aeaf3f1806b" }, "max" : { "_id" : "7496a0fb2877cf18" }, "lastmod" : { "t" : 222000, "i" : 2 } }, "right" : { "min" : { "_id" : "7496a0fb2877cf18" }, "max" : { "_id" : "74fa5d10c4e68473" }, "lastmod" : { "t" : 222000, "i" : 3 } } } }
{ "_id" : "mongotest-25-2011-10-17T23:35:41-120", "server" : "mongotest-25", "clientAddr" : "192.168.0.150:56639", "time" : ISODate("2011-10-17T23:35:41.690Z"), "what" : "moveChunk.start", "ns" : "testdatabase.testcollection", "details" : { "min" : { "_id" : "742e4aeaf3f1806b" }, "max" : { "_id" : "7496a0fb2877cf18" }, "from" : "ShardTest025", "to" : "ShardTest030" } }
{ "_id" : "mongotest-30-2011-10-17T23:35:42-29", "server" : "mongotest-30", "clientAddr" : "(NONE)", "time" : ISODate("2011-10-17T23:35:42.706Z"), "what" : "moveChunk.to", "ns" : "testdatabase.testcollection", "details" : { "min" : { "_id" : "742e4aeaf3f1806b" }, "max" : { "_id" : "7496a0fb2877cf18" }, "step1" : 3, "step2" : 0, "step3" : 817, "step4" : 0, "step5" : 188 } }
{ "_id" : "mongotest-25-2011-10-17T23:35:42-121", "server" : "mongotest-25", "clientAddr" : "192.168.0.150:56639", "time" : ISODate("2011-10-17T23:35:42.710Z"), "what" : "moveChunk.commit", "ns" : "testdatabase.testcollection", "details" : { "min" : { "_id" : "742e4aeaf3f1806b" }, "max" : { "_id" : "7496a0fb2877cf18" }, "from" : "ShardTest025", "to" : "ShardTest030" } }
{ "_id" : "mongotest-25-2011-10-17T23:35:42-122", "server" : "mongotest-25", "clientAddr" : "192.168.0.150:56639", "time" : ISODate("2011-10-17T23:35:42.917Z"), "what" : "moveChunk.from", "ns" : "testdatabase.testcollection", "details" : { "min" : { "_id" : "742e4aeaf3f1806b" }, "max" : { "_id" : "7496a0fb2877cf18" }, "step1" : 0, "step2" : 6, "step3" : 2, "step4" : 1001, "step5" : 15, "step6" : 201 } }
splitの場合
{ "_id" : "mongotest-25-2011-10-17T23:35:25-119", "server" : "mongotest-25", "clientAddr" : "192.168.0.150:56639", "time" : ISODate("2011-10-17T23:35:25.666Z"), "what" : "split", "ns" : "testdatabase.testcollection", "details" : { "before" : { "min" : { "_id" : "742e4aeaf3f1806b" }, "max" : { "_id" : "74fa5d10c4e68473" }, "lastmod" : { "t" : 203000, "i" : 1 } }, "left" : { "min" : { "_id" : "742e4aeaf3f1806b" }, "max" : { "_id" : "7496a0fb2877cf18" }, "lastmod" : { "t" : 222000, "i" : 2 } }, "right" : { "min" : { "_id" : "7496a0fb2877cf18" }, "max" : { "_id" : "74fa5d10c4e68473" }, "lastmod" : { "t" : 222000, "i" : 3 } } } }

split表示が出ていれば、そのタイミングでデータのsplitが実行されたということです。

moveChunkの場合
{ "_id" : "mongotest-25-2011-10-17T23:35:41-120", "server" : "mongotest-25", "clientAddr" : "192.168.0.150:56639", "time" : ISODate("2011-10-17T23:35:41.690Z"), "what" : "moveChunk.start", "ns" : "testdatabase.testcollection", "details" : { "min" : { "_id" : "742e4aeaf3f1806b" }, "max" : { "_id" : "7496a0fb2877cf18" }, "from" : "ShardTest025", "to" : "ShardTest030" } }
{ "_id" : "mongotest-30-2011-10-17T23:35:42-29", "server" : "mongotest-30", "clientAddr" : "(NONE)", "time" : ISODate("2011-10-17T23:35:42.706Z"), "what" : "moveChunk.to", "ns" : "testdatabase.testcollection", "details" : { "min" : { "_id" : "742e4aeaf3f1806b" }, "max" : { "_id" : "7496a0fb2877cf18" }, "step1" : 3, "step2" : 0, "step3" : 817, "step4" : 0, "step5" : 188 } }
{ "_id" : "mongotest-25-2011-10-17T23:35:42-121", "server" : "mongotest-25", "clientAddr" : "192.168.0.150:56639", "time" : ISODate("2011-10-17T23:35:42.710Z"), "what" : "moveChunk.commit", "ns" : "testdatabase.testcollection", "details" : { "min" : { "_id" : "742e4aeaf3f1806b" }, "max" : { "_id" : "7496a0fb2877cf18" }, "from" : "ShardTest025", "to" : "ShardTest030" } }
{ "_id" : "mongotest-25-2011-10-17T23:35:42-122", "server" : "mongotest-25", "clientAddr" : "192.168.0.150:56639", "time" : ISODate("2011-10-17T23:35:42.917Z"), "what" : "moveChunk.from", "ns" : "testdatabase.testcollection", "details" : { "min" : { "_id" : "742e4aeaf3f1806b" }, "max" : { "_id" : "7496a0fb2877cf18" }, "step1" : 0, "step2" : 6, "step3" : 2, "step4" : 1001, "step5" : 15, "step6" : 201 } }
moveChunkの簡単な動き

moveChunkは以下の様な手順で行われます。
ソースで言うと、mongo/s/d_migrate.cpp になります。(これは2.0系のソース)

  1. オプション解析
  2. 分散ロック
  3. moveChunk開始 読み取りロックかけながら、徐々にデータ転送するため全ソートデータとディスクロックをかける
  4. データ転送が終わるまで停止
  5. ロック configサーバロックして、migrateが終わったらconfigサーバアップデートして、changelogコレクションの更新
  6. 転送元のCursorが期限切れになるのを待つ
  7. 元データ削除
changelogコレクションでの表示

これはwhatの項目で示されていますが、以下の順番でステータスが変わっていきます。
moveChunk.start -> moveChunk.to -> moveChunk.commit -> moveChunk.from
moveChunk.from まで終われば、元データの削除まで終わり、moveChunkは終了していると見て問題ありません。


MongoDB in Action

MongoDB in Action