Couchbaseの全キーの一覧を出す

Couchbaseの特定バケットの全キーを一覧で見ることは出来ないか?と会社の先輩に尋ねられました。

Couchbaseの管理画面でもバケットのキーを見ることが出来ます。
管理画面で
[Data Buckets] - [該当バケットのDocuments] - [右上の数字のプルダウンメニュー]
という順番でたどっていけば。

が、管理画面だと最大100件ずつ見ることが出来るのですが、
実際にキー一覧を見たかったバケットには400万以上のキーがあったので100件ずつ見ていくのは現実的ではありませんでした。

どうしたもんかと思っていましたが、調べてゴニョゴニョやってみたところ出来ました!

なので以下の方法で出力しました。
そのメモです。


まず、バケットのバックアップデータがあることが条件です。
Couchbaseのバックアップは以下の前回書いた記事を参照してください。
Couchbaseのバックアップ

環境

OS CentOS 6.4
Couchbaseバージョン couchbase-server-2.0.1-170


バックアップデータを調べてみる

以下のディレクトリにdata-0000.cbbというCouchbaseのバックアップデータがあったとします。

ダンプデータ /tmp/bucket-test/node-10.0.0.1%3A8091/data-0000.cbb


fileコマンドで見てみるとSQLite形式のデータのようです。

file /tmp/bucket-test/node-10.0.0.1%3A8091/data-0000.cbb: SQLite 3.x database, user version 2004


ファイル指定で読み込み

以下のようにしてバックアップデータを読み込みます。

sqlite3 /tmp/bucket-test/node-10.0.0.1%3A8091/data-0000.cbb


テーブル確認

sqliteコマンド操作が出来るようになりますので、テーブル情報を確認してみます。

sqlite> .tables
cbb_meta  cbb_msg


中身を表示

select文を打ってどんなデータが入っているか見てみます。

select * from cbb_msg limit 1; 
65|825|testkey1|0|0|1806126030242609||12345

なんかそれっぽいデータが出てきました。

スキーマ情報表示

それっぽいのは分かりましたが、中にはなんだこれ?というものもあったのでスキーマを表示してみます。

sqlite> .schema cbb_msg
CREATE TABLE cbb_msg
                     (cmd integer,
                      vbucket_id integer,
                      key blob, flg integer, exp integer, cas text,
                      meta blob, val blob);


keyのみ表示

当初の目的であったkeyのみselectしてみます。

sqlite> select key from cbb_msg;
testkey1
testkey2
testkey3
(略)

おお!これでなんとかなりそうです。

キー一覧をファイルに保存

400万件以上のキー一覧を出すのでファイルに書き出したいところ。
以下のようにしてファイルに出力させました。

.output /tmp/allkey.txt

↑このコマンドを打った後は出力が全部ファイル(/tmp/allkey.txt)に保存されます。

で、この間に

select key from cbb_msg;

ともう一度select文を打ってファイルに出力させます。

再び出力をコンソール画面に戻すには

.output stdout

とすればOKです。

sqliteを終了する時

ファイルの書き出しが終わったら以下のコマンドで抜けられます。

.exit


スクリプトを書いてみました。

上記の通りsqliteでselect文を叩けばファイルに書きだすことが出来ましたが、
Couchbaseサーバーが4台あって、バックアップデータが4個あったので4回同じことするのがちょっとなーと思ったので書いてみました。

使い方
php couchbasekey.php /tmp/bucket-test/node-10.0.0.1%3A8091/data-0000.cbb /tmp/allkey.txt

第1引数:ダンプファイル
第2引数:出力ファイル名

<?php

try{
        $db = new SQLite3($argv[1], SQLITE3_OPEN_READONLY);
        $r = $db->query("SELECT key FROM cbb_msg");

        while($key = $r->fetchArray()) {
                $fp = fopen($argv[2], "a");
                fwrite($fp, "$key[0]\n");
        }

        $db->close();
        fclose($fp);

} catch(Exception $e) {
     echo $e->getMessage(),"\n";
}

key以外にvalueなども出したい場合は以下のようにして、
スキーマから必要な情報を持ってきて代入してあげれば良いと思います。
↓の例ではkeyとvalueをカンマ区切りで出すようにしています。

<?php

try{
        $db = new SQLite3($argv[1], SQLITE3_OPEN_READONLY);
        $r = $db->query("SELECT * FROM cbb_msg");

        while($kv = $r->fetchArray()) {

                $fp = fopen($argv[2], "a");
                fwrite($fp, "$kv[key],$kv[val]\n");
        }

        $db->close();
        fclose($fp);

} catch(Exception $e) {
     echo $e->getMessage(),"\n";
}