MySQLなどのダンプデータを読み込むときに進捗を表示する

ちょっと前にpvを知ったのだけど結構知らない人が居そう?なので。

Linuxにはpv(progress viewerの略かな?)という大変便利なコマンドがあり、これはファイルを読み込み標準出力に内容を出力するのですが、標準エラー出力にはどこまで標準出力に内容を出したかを進捗表示してくれます。なので、パイプで標準入力からデータを読み込むタイプのプログラムには汎用的に使えます。

$ echo "中身だよ" > text.txt
$ pv text.txt 2>/dev/null
中身だよ
$ pv text.txt 1>/dev/null
 13 B 0:00:00 [ 746KiB/s] [===========>] 100%

実際に実行すると、矢印で進捗を表示してくれると同時に、ETA(予想残時間)も表示してくれます。便利だね。

たとえば、mysqlで巨大なsqlファイル(ダンプとか)を実行するときなどに役立ちます。

$ pv dump.sql | mysql -uxxx -p db_name

という感じで。

ただ、tsv形式になってるダンプデータでmysqlimportコマンドを使わないといけないときとか、標準入力に対応していない気の利かないプログラムではこの方法は使えません。その場合は、ファイルディスクリプタの情報をwatchで見るなどすると進捗を確認できます。ちょっと手間ですが。

具体的には、/proc/[pid]/fdinfo下に開いているディスクリプタを見ます。まずは、プロセスのpidを調べ、/proc[pid]/fdをlsしてみます。

$ ls -l /proc/12345/fd
合計 0
lrwx------ 1 foo foo 64 12月 27 16:11 0 -> /dev/pts/19
lrwx------ 1 foo foo 64 12月 27 16:11 1 -> /dev/pts/19
lrwx------ 1 foo foo 64 12月 27 16:11 2 -> /dev/pts/19
lrwx------ 1 foo foo 64 12月 27 16:11 3 -> socket:[12345]
lr-x------ 1 foo foo 64 12月 27 16:11 4 -> /home/foo/baa/aho/unko/text.txt

開いてるファイルの番号が分かったら、watchで/proc/[pid]/fdinfo/xを周期的に確認してみます。

$ watch -n 1 -d cat /proc/12345/fdinfo/4
Every 5.0s: cat /proc/12345/fdinfo/4

pos:    7743250432
flags:  02100000
mnt_id: 25

こっちだとポジション(つまりバイト単位の読み出し位置)しか表示されないので若干分かりにくいですが、今どの辺まで読んだかは調べることが出来ます。ランダムアクセスするようなものでは役に立たないですが、まあそういう理由で困ることはあんまり無いでしょう。

以上、小ネタでした。