勉強のためにMySQLをインストールしてデータを投入してみたはいいものの…バンドルされている標準のmysqlコマンドラインクライアントは、
今回はそんな悩みを解決するためのmysqlコマンドラインクライアントのTIPSとして、pagerサブコマンドを紹介します。この機能はmysqlコマンドラインクライアントの機能であるため、mysqlコマンドラインクライアント
デモンストレーション環境について
去る2015/
が、mysql-community-release-*.rpmだったファイル名が、mysql57-community-release-*.rpmに変わっています)
なお、mysqlコマンドラインクライアントのバージョンを確認するには、--versionオプションを利用します
$ /usr/mysql/5.7.9/bin/mysql --version ### MySQL 5.7のコマンドラインクライアント /usr/mysql/5.7.9/bin/mysql Ver 14.14 Distrib 5.7.9, for Linux (x86_64) using EditLine wrapper $ /usr/mysql/5.6.27/bin/mysql --version ### MySQL 5.6のコマンドラインクライアント /usr/mysql/5.6.27/bin/mysql Ver 14.14 Distrib 5.6.27, for Linux (x86_64) using EditLine wrapper $ /usr/mysql/5.5.46/bin/mysql --version ### MySQL 5.5のコマンドラインクライアント /usr/mysql/5.5.46/bin/mysql Ver 14.14 Distrib 5.5.46, for Linux (x86_64) using EditLine wrapper
オプション記法の約束事
本題に入る前に、mysqlコマンドmysqlコマンドやmysqldumpコマンドなどのクライアント、mysqldコマンドも同様です)
mysqlコマンドの解釈する、-u--user)
mysql -u root(ショートオプション 空白文字 値)mysql -uroot(ショートオプション 値)mysql --user root(ロングオプション 空白文字 値)mysql --user=root(ロングオプション イコール 値)
ただし、-pまたは--password)
これは、-pオプションは-pに空白値のパターンが許されたとすると、mysql -p database1は-p'your_もしくは--password='your_の形式しか取れないことを憶えておいてください。
pagerオプション
mysqlコマンドにページャーを指定するには、--pagerオプションを指定するか、pagerサブコマンドを利用します。百聞は一見に如かずと言います。まずは--pagerオプションにlessコマンドを指定して試してみましょう。
$ mysql --pager=less mysql> SELECT NOW();
おわかりいただけたでしょうか。SELECT NOW()ステートメントの結果がいつも通りターミナルに流れるのではなく、lessコマンドに渡されたかのように振る舞います。このステートメントでは1行しか結果が返らないので感慨が薄いのですが…そうですね、
mysql> SHOW TABLES FROM information_schema;
information_データベースに含まれるテーブルを一覧するためのSQLですが、lessコマンドの意味があるのではないでしょうか。さてこの出力結果を見ていると、INNODB_*というテーブルがいくつかあるのが目につきました。lessコマンドにつなぐことができるのであれば、grepコマンドにつなぐことも簡単です。出力結果からINNODB_*にマッチしそうなテーブルだけをページャーを使ってフィルタリングしてみます。
$ mysql --pager="grep 'INNODB_'" mysql> SHOW TABLES FROM information_schema;
想像した通りに出力されたでしょうか? カラム名の表示やASCIIで引かれた罫線だけの行は出力されませんでした。
これは、mysqlコマンドの出力結果をそのまま全てgrepコマンドに渡したため、grepコマンドによってフィルタリングされてしまったからです。またその一方で、61 rows in set (x.の行は"INNODB_"を含まないにも関わらずフィルタリングされることなく出力されています。これはこの行を出力する部分だけがページャーを通さずに直接sprintfでバッファに書き込まれているためなのですが、
さて、pagerオプションにはgrepコマンドでフィルタリングをしつつ、lessコマンドに渡す、
$ mysql --pager="grep 'INNODB_' | less" mysql> SHOW TABLES FROM information_schema;
とても簡単ですね。しかし、mysqlコマンドを一度終了してpagerオプションをセットするのは少し面倒です。mysqlコマンドで接続したままページャーを切り替えるためのサブコマンドmysqlコマンド以外のシェルから起動するコマンドと混同を避けるため、mysqlコマンド内のpagerサブコマンドです。そのまんまですね。
pagerサブコマンド
mysql> pager wc
mysql> SHOW TABLES FROM information_schema;
65 189 2730
61 rows in set (0.14 sec)
上記の例は、pagerサブコマンドを利用してページャーをwcコマンドに変更した例です。引数なしのwcコマンドに引き渡したため、pagerサブコマンドはpagerオプションと同じように空白やパイプを含んだページャーを指定することができますが、pagerサブコマンドに渡すコマンド全体をクォートしてはいけません。
mysql> pager "grep -v INNODB_" PAGER set to '"grep -v INNODB_"' mysql> SHOW TABLES FROM information_schema; sh: grep -v INNODB_: コマンドが見つかりません 61 rows in set (0.21 sec)
クォートしてしまうと、pagerサブコマンドに渡すページャーは、
設定したページャーを元に戻すには、nopagerサブコマンドを実行します。nopagerサブコマンドはpagerサブコマンドで指定したページャーのみならず、pagerオプションで指定した値も無効化して標準出力に戻します。
mysql> nopager PAGER set to stdout
便利なページャー
さて、
less何はなくとも
lessコマンドです。出力結果が長くなる時、キーボードだけでスクロールできるのはとにかく便利です。たとえば、 シリアルコンソールでログインして作業をする場合 (つまり、 ターミナルのスクロールができない場合) などはこれが無いと泣きたくなってしまいます。 lessですので出力内容を検索することもできます。なお、
mysqlコマンドラインクライアントはMySQLサーバからの転送を全てバッファリングしてからページャーを起動するため、巨大な結果セットに対して 「末尾を参照する」 ( lessコマンド内で"G")などの操作をしても、 そのタイミングでは通信は発生しません (すでに送信済みのものをクライアント側で操作します)。つまり、 先頭の1ページだけ見て lessコマンドを終了してしまう場合でも、結果セットの全てが転送されます。この動作を変更して、 lessのページング動作に合わせて通信を発生させたい場合は、mysqlコマンドラインクライアントに-q( --quick)オプションを指定します。 grep -v SleepSHOW PROCESSLISTを見る時によく使います。スリープしているスレッドを除外した、今動いているスレッドのみを一覧することができ、 とても便利です。派生として egrep -v Sleep|Binlog|handlersocketなどもあります(レプリケーションスレーブのステータスである Binlog DumpやBinlog GTID Dump、HandlerSocketプラグインのスレッドも除外) cat > /dev/null 結果セットを全て
/dev/にリダイレクトし、null 何も表示させません。主に、 結果セットが大きく画面に表示したくない、 かつ、 レスポンスタイムのみ確認したい場合や、 キャッシュに載せるためだけに実行する場合に利用します。ただし、 lessの時と同じく何も表示されないとはいえ、MySQLサーバは mysqlコマンドラインクライアントに対して結果セットを送信しきっており、mysqlコマンドラインクライアント側で破棄されるだけであることに注意してください。wc結果セットのサイズをとてもざっくりと計るために使います
(行ヘッダや罫線が含まれている分の誤差や結果セット以外のプロトコルのやり取りなどがありますので、 正確な転送量ではありません)。正確ではないとはいえ、 この値で40MBもの値が返ってきたらそれは結果セットのサイズが大きすぎるんじゃないか…という推測の時に使ったりします。 teeteeコマンドを通せばオペログが取れるんじゃないか! という思いもありますが、残念、 ページャーが通るのはクエリの結果だけなので、 肝心の実行したクエリーを記録することができません。そもそもそういう用途に teeオプションやteeサブコマンドがあります。
他にもvim -R -、gzip -c > /tmp/、ssh ipaddr "cat - > ~/result.、loggerなど、
