LOB のデータを CLI からファイルにダンプする方法
- お題 : 「BLOB のカラムをコマンドのみでファイルにダンプする」
ということで、非バイナリアンな私は Cafe Babe 程度のたしなみしかないですが、LOB のカラムの中身をちょいっと拝見したい時もあるわけです。
コード書いてバイト配列書き出せば良いのだけれど、例えば Python だったら DB API をインストールして、とか、そういう環境的な準備が面倒な時に、まぁ、それなりの精度でダンプ出来る方法を、ということで。環境は MySQL 5.1.x です。
下準備
以下のような形で LOB のデータを入れておく
mysql> create table lobtest (id int,lob longblob); mysql> insert into lobtest (id,lob) values (1,load_file('/Users/someda/test.gif'));
抜き出し
$ mysql -Ns -u root -p -e "SELECT hex(lob) FROM lobtest WHERE id = 1" | awk '{s=$1;len=length(s); for(i=1;i<=len;i=i+60){print substr(s,i,60)}}' | xxd -r -ps -c 30 > out.gif
やっていることは、
- LOB のデータを 16 進数で文字表現で抜き出してから、
- awk で 30byte 毎に改行を入れた形式に変換して、
- それを xxd で戻す
という 3 ステップの組み合わせです。特にバッファしたりせず、データ全てをメモリに乗せるので、あまり大きなサイズの LOB には使わないほうが良いかも。ただ、手元環境で、2010年度でそれなりに近代的なマシンでは 100MB 程度ならば動く感じでした。
抜き出すファイルのサイズによってはエラーが出ることもあるので、mysql のオプションに --max_allowed_packet=48M とか (サイズは適当) をつければ解消することもあるかと思います。
確認と雑感
$ cksum test.gif out.gif 3114775889 1442 test.gif 3114775889 1442 out.gif
通常のバイナリだったら、この方法で zip やら画像やら xls やらは普通にダンプ出来たのですが、逆にテキストファイルで、日本語のエンコード処理がかかっているようなモノが怪しい時がありました。
専用のユーティリティがあるような気もするのですが、そこは MySQL 初心者ということで。。。
追記 (7/7)
天の声が聞こえました。
GNU textutils はいらんかえ〜♪ fold -w 60 - ... はっ、Kyushu-AWKers と言いながら AWK を排除してしまった(w RT @tksmd: ブログ書きました。 http://d.hatena.ne.jp/tksmd
http://twitter.com/matsu_hiroshi/status/17845462804
ということで、awk が消えて fold が登場しました。
$ mysql -Ns -u root -p -e "SELECT hex(lob) FROM lobtest WHERE id = 1" | fold -w60 | xxd -r -ps -c 30 > out.gif