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

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

やっていることは、

  1. LOB のデータを 16 進数で文字表現で抜き出してから、
  2. awk で 30byte 毎に改行を入れた形式に変換して、
  3. それを 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