2013年10月28日月曜日

MySQL Casual Talks vol.5 でバーボンハウスしてきた

やあ(´・ω・`)
ようこそ、バーボンハウスへ。



というわけで、MySQL Casual Talks vol.5に参加してきました。
ハッシュタグもちょこちょこ拾ってあるので、ブログ書いた方などは追加していただけると幸いです。

今回は前の週のOSC 2013 Tokyo/Fallで死んでたのでさっくり愚痴って15分! とか思ってたんですが、前々日に30ページまで書いて5分しか保たずにあわてて追加していったらなんか60ページくらいになってしまったという。それでもやっぱり10分くらいでやったみたいですが、一発ネタなのでそれくらいで終わって良かったですね。

内容については概ね`本当にあった怖くない話'なんですが、1つのテーブルじゃなくて2つ3つのテーブルのイケてないところを寄せ集めてデフォルメした感じです。

あとはvarbinary型が色々あると思いますが、utf8mb4で40文字入れるだけで161bytes対41bytesになって、BIGINTだDATETIMEだTINYINTだ言ってるのが馬鹿馬鹿しいくらいの差になるので、容量がタイトな時はvarbinary型にしています。スッカスカな時は別にjsonをTEXT型に突っ込んでも(それほど)文句は言いません。

あと、カラム名をインデックス名に流用する時は 必ず カラムと全く同じ名前のインデックスにならないように、ALTER TABLE .. DROP KEY ..のKEYキーワードを忘れてもカラムがドロップされたりしないように 気をつけて下さい。

じゃあ、バリウム飲んできます(健康診査

2013年10月16日水曜日

5.1.72のmysql_upgrade --skip-write-binlogでスクリプトが転けるバグ

昨日、MySQL 5.0.83から5.1.72へのバージョンアップをしてたんですが、バイナリー入れ替えてmysql_upgradeかけても何か様子がおかしい。
前に5.0.83に上げた時にmysql_upgrade忘れてたんじゃないかと疑ってたんですが、実際5.1.72のmysql_upgradeのバグっぽいです。ごめんとなりのひと。

http://dev.mysql.com/doc/refman/5.1/en/mysql-upgrade.html


mysql_upgradeに--skip-write-binlogまたは--write-binlogのオプションを引き渡すと、実行されるべき`mysql_fix_privilege_tables'のクエリーが全て転けてアップグレードできない、というもの。
取り敢えず5.1.72のmysql_upgradeで確認しましたが、どこで混入したのかは謎。


$ gdb --args mysql_upgrade --socket=/xxx/mysql.sock -uroot -p'xxx' --skip-write-binlog

brake mysql_check.c:770 and go on.

770   run_query(mysql_fix_privilege_tables,
771             &ds_result, /* Collect result */
772             TRUE);

(gdb) bt full
#0  run_tool (tool_path=, ds_res=0x7fffffffe7f0) at mysql_upgrade.c:372
        ret = 
        arg = 
        args = {{gp_offset = 48, fp_offset = 0, overflow_arg_area = 0x7fffffffe170, reg_save_area = 0x7fffffffe060}}
        ds_cmdline = {
          str = 0x610650 "'/home/yoku0825/mysql-5.1.72/client/mysql' '--no-defaults' '--socket=/xxx/mysql.sock' '--user=root' '--password=xxx' '--write-binlog' '--user=root'  '--database=mysql' '--batch' '--"..., length = 240,
          max_length = 512, alloc_increment = 512}
#1  0x00000000004019bf in run_query (ba
    query=0x4028b0 "-- Copyright (c) 2007, 2008 MySQL AB, 2009 Sun Microsystems, Inc.\n -- Use is subject to license terms.\n -- \n -- This program is free software; you can redistribute it and/or modify\n -- it under the te"...,
    ds_res=0x7fffffffe7f0, force=1 '\001') at mysql_upgrade.c:497
        ret = 
        fd = 7
        query_file_path = "/tmp/sqlQG2xcV", '\000' "\220, \353\200\313>\000\000\000\200\027\365\312>", '\000' , "\b\000\000\000\060\000\000\000\300\343\377\377\377\177\000\000\000\343\377\377\377\177", '\000' , "#\245\306\312>", '\000' "\200, \027\365\312>\000\000\000(\000\000\000\000\000\000\000\n\000\000\000\000\000\000\000\000\000\253\252\252*\000\000\066\244\306\312>\000\000\000\000\002\000\000\000\000\000\000\200\027\365\312>\000\000\000\200\027\365\312>\000\000\000\n\000\000\000\000\000\000\000\360\347\377\377\377\177\000\000\264\253\306\312>\000\000\000\200\027\365\312>\000\000\000\224\342@\000\000\000\000\000\200\027\365\312>\000\000\000\020\374\305\312>\000\000\000\224\342@\000\000\000\000\000\032\025@\000\000\000\000\000\b\000\000\000\060\000\000\000\300\343\377\377\377\177\000\000\000\343\377\377\377\177\000\000\020\000a\000\000\000\000\000\331\342@\000\000\000\000\000"...
        sql_log_bin = "SET SQL_LOG_BIN=0;"
#2  0x000000000040211c in run_sql_fix_privilege_tables (argc=0, argv=0x6102f8) at mysql_upgrade.c:770
        found_real_errors = 0
        ds_result = {str = 0x610420 "/home/yoku0825/mysql-5.1.72/client/.libs/lt-mysql: unknown option '--write-binlog'\n",
          length = 82, max_length = 512, alloc_increment = 512}
#3  main (argc=0, argv=0x6102f8) at mysql_upgrade.c:872
        self_name = "/home/yoku0825/mysql-5.1.72/client/.libs/mysql_upgrade", '\000' 
(gdb)
(gdb) p *ds_res
$1 = {str = 0x610420 "/home/yoku0825/mysql-5.1.72/client/.libs/lt-mysql: unknown option '--write-binlog'\n", length = 82,
  max_length = 512, alloc_increment = 512}


mysql_upgradeがテンポラリーファイルにアップグレード用のステートメントを書き出し(この時、--skip-write-binlogならファイルの先頭に"SET SQL_LOG_BIN= 0;"を書き込む)、mysqlコマンドラインクライアントを呼んでそのファイルを食わせる、という流れで実際のALTERが行われる手筈になっているのだけれど、その時にmysql_upgradeが--skip-write-binlog, --write-binlogオプションをmysqlコマンドラインクライアントに渡してしまうのが問題で、unknown optionって怒られる羽目に遭う。

mysql_upgrade --skip-write-binlogの時はmysql .. --write-binlog .. --skip-write-binlogの両方を渡して、後から渡した--skipの方でオーバーライドさせてる、mysql_upgrade --write-binlogの時はmysql .. --write-binlog ..と渡してる。
どっちも指定されていない時はどちらのオプションもmysqlに渡さず、5.1では暗黙のデフォルトとして--write-binlog扱いになり、"SET SQL_LOG_BIN= 0;"は書き込まれない。

--write-binlogオプションを押し込むところを--loose-write-binlogにして、mysql_upgradeに渡すのを--loose-skip-write-binlogにすれば何とかなるかな、と思いつつパッチでも書こうかしら。でも電車動き始めたらしいのでそろそろ出勤するかな。

ちなみにこれ、MySQL Bugsにも上げたんですが、backtraceの中にパスワードとか残したままにしてしまって、しかもBugsは後から投稿取り消せないのでモニョモニョな状態になってコメントで泣きついたところ、Access deniedにしてもらいました。

「Oracle様にとってはゴミ屑のようなコミュニティエディションの1ユーザーの懇願など無視されるかな」と思ってたんですが、数時間でさっくり対応してくれて感謝感謝です。
正直ちょっと(だけ)見直した。

MySQL Bugs #70624 mysql_upgrade with --skip-write-binlog doesn't work
http://bugs.mysql.com/bug.php?id=70624


【2013/10/16 16:05】
パッチ書きました。

https://gist.github.com/yoku0825/7003161

【2013/10/24 12:29】
本家でもVerifyされたので、次のリリースでは直るといいなー。

2013年10月7日月曜日

ラッパーも含めて mysqldが起動するときにどのmy.cnfを舐めてるのか知りたいとき

いやまあ、マニュアルに書いてあるけど。
http://dev.mysql.com/doc/refman/5.6/en/option-files.html

Linuxで公式MySQL、--defaults-file, --defaults-extra-fileを指定しない場合は、

  • /etc/my.cnf
  • /etc/mysql/my.cnf
  • /usr/local/mysql/etc/my.cnf
    • SYSCONFDIR/my.cnfのこと。
    • 公式のバイナリーはSYSCONFDIR== /usr/local/mysql/etc。cmakeのオプションで変えられる。
    • MariaDBはこいつが設定されていないっぽい。
  • /usr/local/mysql/my.cnf
    • $MYSQL_HOME/my.cnfのこと。
    • basedirを設定してれば$MYSQL_HOME== basedirになる。
  • /home/mysql/.my.cnf
    • $HOME/.my.cnfのこと。コイツだけドットファイル。
の順番で読む。
とはいえこんなのめんどくさくて憶えてられなかったり、SYSCONFDIRやMYSQL_HOMEが思いもしない変なところになってたりすることがあったりなかったりするかも知れないので、調べ方だけメモってみる。


# strace -ff -e open -e stat /usr/mysql/5.5.34/bin/mysqld_multi start 55,56 2>&1 | grep "my\.cnf"

[pid  7359] stat("/etc/my.cnf", {st_mode=S_IFREG|0644, st_size=3584, ...}) = 0
[pid  7359] stat("/etc/mysql/my.cnf", 0x7fffa1322e40) = -1 ENOENT (No such file or directory)
[pid  7359] stat("/usr/local/mysql/etc/my.cnf", 0x7fffa1322e40) = -1 ENOENT (No such file or directory)
[pid  7359] stat("/root/.my.cnf", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat("/etc/my.cnf", {st_mode=S_IFREG|0644, st_size=3584, ...}) = 0
stat("/etc/my.cnf", {st_mode=S_IFREG|0644, st_size=3584, ...}) = 0
stat("/etc/mysql/my.cnf", 0x1739130)    = -1 ENOENT (No such file or directory)
stat("/usr/mysql/5.5.34/my.cnf", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat("/usr/mysql/5.5.34/my.cnf", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat("/root/.my.cnf", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat("/root/.my.cnf", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
[pid  7361] stat("/etc/my.cnf", {st_mode=S_IFREG|0644, st_size=3584, ...}) = 0
[pid  7361] stat("/etc/mysql/my.cnf", 0x7fffdaeb46e0) = -1 ENOENT (No such file or directory)
[pid  7361] stat("/usr/local/mysql/etc/my.cnf", 0x7fffdaeb46e0) = -1 ENOENT (No such file or directory)
[pid  7361] stat("/root/.my.cnf", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
[pid  7365] stat("/etc/my.cnf", {st_mode=S_IFREG|0644, st_size=3584, ...}) = 0
[pid  7365] stat("/etc/mysql/my.cnf", 0x7fff4038abf0) = -1 ENOENT (No such file or directory)
[pid  7365] stat("/usr/local/mysql/etc/my.cnf", 0x7fff4038abf0) = -1 ENOENT (No such file or directory)
[pid  7365] stat("/root/.my.cnf", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
[pid  7371] stat("/usr/mysql/5.6.14/data/my.cnf", 0x7fff0d4bc2b0) = -1 ENOENT (No such file or directory)
[pid  7371] stat("/usr/mysql/5.6.14/my.cnf", 0x7fff0d4bc2c0) = -1 ENOENT (No such file or directory)
[pid  7371] stat("/usr/mysql/5.6.14/data/my.cnf", 0x7fff0d4bc320) = -1 ENOENT (No such file or directory)
[pid  7407] stat("/etc/my.cnf", {st_mode=S_IFREG|0644, st_size=3584, ...}) = 0
[pid  7407] stat("/etc/mysql/my.cnf", 0x7fff380ae700) = -1 ENOENT (No such file or directory)
[pid  7407] stat("/usr/local/mysql/etc/my.cnf", 0x7fff380ae700) = -1 ENOENT (No such file or directory)
[pid  7407] stat("/usr/mysql/5.6.14/my.cnf", 0x7fff380ae700) = -1 ENOENT (No such file or directory)
[pid  7407] stat("/root/.my.cnf", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
[pid  7364] stat("/usr/mysql/5.5.34/data/my.cnf", 0x7fffb0b1a980) = -1 ENOENT (No such file or directory)
[pid  7364] stat("/usr/mysql/5.5.34/my.cnf", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
[pid  7364] stat("/usr/mysql/5.5.34/data/my.cnf", 0x7fffb0b1a990) = -1 ENOENT (No such file or directory)
[pid  7364] stat("/usr/mysql/5.5.34/data/my.cnf", 0x7fffb0b1a9f0) = -1 ENOENT (No such file or directory)
[pid  7421] stat("/etc/my.cnf", {st_mode=S_IFREG|0644, st_size=3584, ...}) = 0
[pid  7421] stat("/etc/mysql/my.cnf", 0x7fffde0a77e0) = -1 ENOENT (No such file or directory)
[pid  7421] stat("/usr/local/mysql/etc/my.cnf", 0x7fffde0a77e0) = -1 ENOENT (No such file or directory)
[pid  7421] stat("/usr/mysql/5.5.34/my.cnf", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
[pid  7421] stat("/root/.my.cnf", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
[pid  8339] stat("/etc/my.cnf", {st_mode=S_IFREG|0644, st_size=3584, ...}) = 0
[pid  8339] stat("/etc/mysql/my.cnf", 0x7fff59e821d0) = -1 ENOENT (No such file or directory)
[pid  8339] stat("/usr/local/mysql/etc/my.cnf", 0x7fff59e821d0) = -1 ENOENT (No such file or directory)
[pid  8339] stat("/usr/mysql/5.6.14/my.cnf", 0x7fff59e821d0) = -1 ENOENT (No such file or directory)
[pid  8339] stat("/root/.my.cnf", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
[pid  8416] stat("/etc/my.cnf", {st_mode=S_IFREG|0644, st_size=3584, ...}) = 0
[pid  8416] stat("/etc/mysql/my.cnf", 0x7fffc5f4d310) = -1 ENOENT (No such file or directory)
[pid  8416] stat("/usr/local/mysql/etc/my.cnf", 0x7fffc5f4d310) = -1 ENOENT (No such file or directory)
[pid  8416] stat("/usr/mysql/5.5.34/my.cnf", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
[pid  8416] stat("/root/.my.cnf", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0


実際どれを開いたかだけでよければ、"-e stat"はイラナイ。
小ネタ、小ネタ。


【2015/02/18 19:39】
mysqldの読むやつ見たいんだったらmysqld --help --verboseでいいじゃん? って何度か言われてたので追記。
mysqld --help --verboseだと、my.cnfに設定したbasedirの値が読み取られる前にパスが解釈されるので、MYSQL_HOME/my.cnfが表示されない。


$ /usr/mysql/5.6.23/bin/mysqld --help --verbose  | grep cnf
/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf
                      my.cnf, $MYSQL_TCP_PORT, /etc/services, built-in default
2015-02-19 19:35:47 29891 [Note] Binlog end
2015-02-19 19:35:47 29891 [Note] Shutting down plugin 'CSV'
2015-02-19 19:35:47 29891 [Note] Shutting down plugin 'MyISAM'

$ strace -f -e stat /usr/mysql/5.6.23/bin/mysqld 2>&1 | grep my\.cnf
stat("/etc/my.cnf", {st_mode=S_IFREG|0644, st_size=4456, ...}) = 0
stat("/etc/mysql/my.cnf", 0x7fffd4f430d0) = -1 ENOENT (No such file or directory)
stat("/usr/local/mysql/etc/my.cnf", 0x7fffd4f430d0) = -1 ENOENT (No such file or directory)
stat("/home/yoku0825/.my.cnf", 0x7fffd4f430d0) = -1 ENOENT (No such file or directory)


$ strace -f -e stat /usr/mysql/5.6.23/bin/mysqld_safe 2>&1 | grep my\.cnf
stat("/usr/mysql/5.6.23/data/my.cnf", 0x7fff56f127f0) = -1 ENOENT (No such file or directory)
stat("/usr/mysql/5.6.23/my.cnf", {st_mode=S_IFREG|0664, st_size=943, ...}) = 0
stat("/usr/mysql/5.6.23/data/my.cnf", 0x7fff56f12800) = -1 ENOENT (No such file or directory)
stat("/usr/mysql/5.6.23/data/my.cnf", 0x7fff56f12860) = -1 ENOENT (No such file or directory)
[pid 28434] stat("/etc/my.cnf", {st_mode=S_IFREG|0644, st_size=4456, ...}) = 0
[pid 28434] stat("/etc/mysql/my.cnf", 0x7ffffdd236c0) = -1 ENOENT (No such file or directory)
[pid 28434] stat("/usr/local/mysql/etc/my.cnf", 0x7ffffdd236c0) = -1 ENOENT (No such file or directory)
[pid 28434] stat("/usr/mysql/5.6.23/my.cnf", {st_mode=S_IFREG|0664, st_size=943, ...}) = 0
[pid 28434] stat("/home/yoku0825/.my.cnf", 0x7ffffdd236c0) = -1 ENOENT (No such file or directory)
[pid 28916] stat("/etc/my.cnf", {st_mode=S_IFREG|0644, st_size=4456, ...}) = 0
[pid 28916] stat("/etc/mysql/my.cnf", 0x7fff43cc1bd0) = -1 ENOENT (No such file or directory)
[pid 28916] stat("/usr/local/mysql/etc/my.cnf", 0x7fff43cc1bd0) = -1 ENOENT (No such file or directory)
[pid 28916] stat("/usr/mysql/5.6.23/my.cnf", {st_mode=S_IFREG|0664, st_size=943, ...}) = 0
[pid 28916] stat("/home/yoku0825/.my.cnf", 0x7fff43cc1bd0) = -1 ENOENT (No such file or directory)
[pid 29004] stat("/etc/my.cnf", {st_mode=S_IFREG|0644, st_size=4456, ...}) = 0
[pid 29004] stat("/etc/mysql/my.cnf", 0x7fff76cacf80) = -1 ENOENT (No such file or directory)
[pid 29004] stat("/usr/local/mysql/etc/my.cnf", 0x7fff76cacf80) = -1 ENOENT (No such file or directory)
[pid 29004] stat("/usr/mysql/5.6.23/my.cnf", {st_mode=S_IFREG|0664, st_size=943, ...}) = 0
[pid 29004] stat("/home/yoku0825/.my.cnf", 0x7fff76cacf80) = -1 ENOENT (No such file or directory)

よく憶えてないんだけど、たぶんこれがラッパーに隠蔽されて(mysql.serverが中でゴニョゴニョやってるとかそんなの)るのが嫌でstraceで取ったんじゃないかなぁと思う。


$ MYSQL_HOME=/usr/mysql/5.6.23 /usr/mysql/5.6.23/bin/mysqld --help --verbose  | grep cnf
/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf /usr/mysql/5.6.23/my.cnf ~/.my.cnf
                      my.cnf, $MYSQL_TCP_PORT, /etc/services, built-in default
2015-02-19 19:35:18 29889 [Note] Binlog end
2015-02-19 19:35:18 29889 [Note] Shutting down plugin 'CSV'
2015-02-19 19:35:18 29889 [Note] Shutting down plugin 'MyISAM'

$MYSQL_HOMEをちゃんと環境変数で与えておけば、mysqld --help --verboseでも見える。

あとはmy.cnfに!include が書いてあるケースとかも--help --verboseでは拾えないなぁとかそんなことをぼんやりと。

Isucon #3に出場してチームをお通夜にしてしまった話

俺の大ポカに巻き込まれたチームメイトの @studio3104 さんと @ayumu83s さんごめんなさい。
俺がしでかしたことをありのまま話すぜ。


  • 取り敢えず吊るしのベンチマークを取る。
  • 開始早々、MySQL 5.6.13をPercona Server 5.6.13に取替え。
    • この時、datadirは使い回しでバックアップを取らなかった。
  • my.cnfをチューニングしてibdata1とib_logfile*を再作成。
    • その間アプリ側ではTCP/IP接続をsocket接続に書き換えてもらったり、プロファイル仕込んでもらったり。
  • この時点からベンチマークが通らなくなる。
    • 原因はInnoDB memcachedを殺したからなんですがこの時点では判らず。
    • アプリ側のコードを切り戻したりPercona ServerをMySQLに戻したりしたけれど、ベンチマークは相変わらずFAILする。
  • すたじおさんの到着も遅れていたし、取り敢えずエラーは後で解析するとして判るところからチューニングを開始することに。
  • テーブルにINDEXをガスガス追加。INSERT, UPDATEのトラフィックは大したことがなさそうだったので、基本covering index狙いの長めのキー。covering indexが狙えないところはORDER BY狙いのキー。
  • Percona Serverだろうとオプティマイザーは残念な感じなので、片っ端からUSE INDEXを付けてインデックスを固定。あと、変なループがあるって教えてもらったのでJOINに書き換え。
    • このJOINも、最終的にはスコアが下がったっていって切り戻したんだけど(´・ω・`)
  • Apacheをnginxに入れ替えたりアプリをデバッグしてもらっても原因が見えないし、general logを眺めていたら"WHERE id=NULL"ってクエリーが㌧でいたので、データがおかしいのかなぁと思ってinit.sql.gzからデータを再投入したり、mysqldumpを吸い上げてリストアしてみたり。当然何も起こらない。
    • ええ、InnoDB memcachedにセッション情報保存してましたから、セッション情報が引き渡されないんですよね。
  • ピンポイントに打ってくるINSERT, UPDATEとSELECTはHandlerSocketかInnoDB memcachedでやっつけるかと思ってNet::HandlerSocketをmake。InnoDB memcached PluginもPercona Serverのバイナリーには入ってなかったのでソース落としてきてmake。
    • innodb_memcache.containersをごにょごにょして何度か再起動するものの、目的の用途に使うには向かないのでHandlerSocketの方が良さそうだと判断。
    • アプリ環境周りのセットアップが全く判っていないので、HandlerSocketのライブラリをmake installしてもパスが通っておらず結局使えない(´・ω・`)
  • SQLは「結果セットを変えない」ことを大前提にちょっと書き換えただけ。
    • 普段の仕事っぷりが見事に出るなぁ。。_| ̄|○
  • 残り1時間、ついにインスタンスを破棄して新しいインスタンスを立ち上げることを決意。
    • 勿論ベンチ通る。
  • Percona Serverに変える。
    • 通らなくなる。
    • ここかよ! だがデータストアが変わっただけで何が変わる?
  • ところでなんかエラーログのInnoDB memcachedのエラー(" InnoDB_Memcached: the value column c2 in table test/demo_test should be INTEGER, CHAR or VARCHAR.")がウザいので、UNINSTALL PLUGIN。
    • 通らなくなる。
    • Σ(゚д゚lll) うっそぉ!?
    • ま・さ・か…!
  • mysql> SELECT * FROM test.demo_test;
  • うわあああああ(AA略
  • Perconaに入れ替えてインデックス作ってSQLにヒント句追加して…ここまでで、時間切れ。


というわけで、@studio3104 さんと @ayumu83s さんに
 8 時 間 耐 久 デ バ ッ グ 祭 り
を強要した挙句、
 責 め る べ き は た だ 一 人
だけど、2人とも優しくて責めるに責められず、結果お通夜に。

MySQLしかいじれなかった結果の最終スコアは3440でした。
本当にごめんなさい。

2013年10月1日火曜日

MySQL 5.7.2のEXPLAIN FOR CONNECTIONの使い方

昨日のMyNA会でちょっと話が出ていたEXPLAIN FOR CONNECTIONの使い方。
正直これそんなに便利なものじゃないと思うんですが。

http://dev.mysql.com/doc/refman/5.7/en/explain.html

{explainable_stmt | FOR CONNECTION connection_id}
となっている通り、EXPLAINに食わせるSQLステートメントの代わりにFOR CONNECTION x; として指定する。


conn1> explain SELECT * FROM t1, t1 AS t2;
+----+-------------+-------+------+---------------+------+---------+------+--------+---------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows   | Extra                                 |
+----+-------------+-------+------+---------------+------+---------+------+--------+---------------------------------------+
|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL | 953856 | NULL                                  |
|  1 | SIMPLE      | t2    | ALL  | NULL          | NULL | NULL    | NULL | 953856 | Using join buffer (Block Nested Loop) |
+----+-------------+-------+------+---------------+------+---------+------+--------+---------------------------------------+
2 rows in set (0.00 sec)

conn1> SELECT * FROM t1, t1 AS t2;
..(実行中)

conn2> show processlist;
+----+------+-----------+------+---------+------+--------------+----------------------------+
| Id | User | Host      | db   | Command | Time | State        | Info                       |
+----+------+-----------+------+---------+------+--------------+----------------------------+
|  3 | root | localhost | d1   | Query   |    5 | Sending data | SELECT * FROM t1, t1 AS t2 |
|  4 | root | localhost | NULL | Query   |    0 | init         | show processlist           |
+----+------+-----------+------+---------+------+--------------+----------------------------+
2 rows in set (0.51 sec)

conn2> EXPLAIN FOR CONNECTION 3;
+----+-------------+-------+------+---------------+------+---------+------+--------+---------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows   | Extra                                 |
+----+-------------+-------+------+---------------+------+---------+------+--------+---------------------------------------+
|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL | 953856 | NULL                                  |
|  1 | SIMPLE      | t2    | ALL  | NULL          | NULL | NULL    | NULL | 953856 | Using join buffer (Block Nested Loop) |
+----+-------------+-------+------+---------------+------+---------+------+--------+---------------------------------------+
2 rows in set (0.25 sec)

こんな感じ。おんなじじゃーん、て。

ところでEXPLAIN FOR CONNECTIONかけるとかけた方のコネクション(id= 3のコネクション)がアボートするんだけどこれバグ?;

【2013/10/01 13:36】
EXPLAIN FOR CONNECTIONかけなくても落ちた。

【2013/10/01 13:40】
OOM Killerに殺されてるだけだった…(´;ω;`)