かみぽわーる

kamipo's blog

好きな子のことかslow query logのことばかり考えてほかのことがおろそかになる性格なおしたい #isucon

ISUCON3 予選おつかれさまでした!

うちのチームのことはだいたいやっぽさんが書いてる通りなんですけど、おもに僕がやったこととかAMI提出後に振り返ってみたことを書いておきます。

振り返りはコチラ。

【ISUCON3】予選の振り返り【ぶっちゅぶす】 - Togetter

まず今回ISUCON3でチームを組む段階で考えていたのは、チームメンバーの共通言語は揃えておいたほうがいい(当たり前と思うかもしれないけど前回バラバラすぎて死んだ)ということと、得意分野がかぶってないチームにしたいと思ってた。その点でいうと、まだ予選がおわったところだけど今まで参加してきた教訓を活かせたと思う。

あとは前回力を出し切れない結果で悔しい思いをしたというのがあって、予選通過すれば次につながるので、横着せずに普段やってることで着実にスコアを伸ばしたい、fujiwaraさんのような役割を目指したいと思ってた。 それも得意分野がかぶってないおかげかまずまずうまくいったのではないかと思う。

だいたい僕がログ見る係でやっぽさんがクソクエリなおしまくってくれてたけど、'/recent/:page'のページャのOFFSETをWHEREに変換するのは僕の得意分野だったんで、こういうことしたいっていってやっぽさんに全部実装してもらったりしてました。あとは基本的にORDER BY 狙いのキーにしていったらMySQLの負荷はなくなりました。

あとこれは別件ですが、世間にはORDER BY created_at DESCする人がとても多いと思ってるんですけど、挿入順に単調増加する値でソートしたいんだったらAUTO_INCREMENTしてるPRIMARY KEYがあるでしょう、なんでそっちでソートしてくれないんすか、created_atにINDEX張るのも空間効率の無駄なのでやめてほしいです。これは5年以上前からいってるけどまったく世間に伝わってないと思うんでORDER BY 狙いのキーといっしょにこれも言い続けていきたいです。

最後に、本選へ向けての教訓としては

  • 好きな子のことかslow query logのことばかり考えてほかのことがおろそかになる性格なおしたい
  • 最初にちゃんとコードを読んで高速化の指針を検討したい

というところですかね。

こちらからは以上です。

YAPC::Asia 2013でmysql-buildのLTしてきた

2日目のLTで、MySQLSQLというDSLをつかって様々なストレージエンジンを共通のインターフェースで抽象化して扱うことのできるフレームワークなわけですがということで、mysql-buildでMySQLプラグインも一緒にビルドする話をしてきました。

mysql-buildでQ4Mやmroongaもビルドしたい

これでQ4Mとか簡単に使い始められるようになるので、みんなMySQLプラグインもつかってくれるかな?

(いいとも!)

動機とか

mysql-buildはMySQL Casual Advent Calendar 2011のときに書いたやつで、そのときからすでにQ4MやHandlerSocketを入れる的なネタが3つも4つもかぶって投稿されて、みんなどんだけQ4M入れたいんだよな感じだったわけですが、僕もそもそもはローカルでLTネタのプラグインとか書くときにソースからビルドしたMySQL環境が頻繁に必要になってたので書いたというのがあります。

なので当時からやる気が出たらプラグインも入れれるようにしようと思ってたけど、MySQL 5.6 で Q4M を動かしたいをやってたときにMySQLのビルドがCMake化したあたりの対応でいろいろハマったりして(これとかこれ)、まぁMySQL 5.5以降のCMakeでのビルドに対応したプラグインは置くべき場所に展開してcmake叩くだけでビルドできるようになってて簡単なんだけど、それも、知らなきゃ簡単かどうか調べるまでが面倒なんでコマンドパツイチで入るほうが敷居下がっていいですよね。僕も忘れたころにまたハマったりするの嫌だし。

現時点だとmysql-buildで指定できるQ4Mとmroongaは、MySQL 5.5以降のCMakeを使ったビルドだけ対応してるんでMySQL 5.1には対応してません(Q4Mとmroonga自体はMySQL 5.1にも対応してる)。僕がMySQL 5.1を使わないんでめっちゃモチベーション低いですが10人ぐらいのおっさんか1人のかわいこちゃんがどうしてもっていうなら対応するかもしれないです。

こちらからは以上です。

Ubuntu で nano が立ち上がってしまうのをなんとかする方法

#mysqlcasual vol.4 でLTしてきました

4/17 に日本オラクルで開催された MySQL Casual #04 で話して来ました。

当日のスライドは以下になります。

SQLがむずかしくて生きるのがつらい

ちょいとまだ作り始めたばっかりで微妙なところも多々あるんですが、mruby_storage_engine のレポジトリは以下になります。

kamipo/mruby_storage_engine · GitHub

発表について

けっこう時間なくて準備にテンパってたので、あとで言及されてるのをみると説明たりてなかったなー(絞り込めないってLIMIT OFFSETの話じゃないの?的な)というところもあったけど、それがわかってる人は大丈夫な人なので大丈夫です!補足ありがとうございます!

mruby_storage_engine について

構想自体は一年前ぐらいからあって、よく同僚に「こういうことできたらうれしいとおもわへん?(でもめんどくさいので実装はしない)」というのを繰り返していたんですが、勉強会ドリブンで実装するチャンスをのがすとまた一年ぐらいめんどくさくてやらない病に陥るので、前日の晩に@さんに発表枠もらって後に引けない状態に追い込んでから徹夜でなんとかデモできるレベルまでもっていきました。

既存技術の組み合わせなんでやる気だせばすぐできると思ったんですが、なんかMySQL 5.6でうごかすことに変にこだわったせいで5.6から変わったところにけっこう苦しむことになって、いちばんやばかったのが、すでにテーブルをlockしてるクエリ内でさらに追加で他のテーブルもlockしようとするとassartに引っかかって落ちること。言い換えると、SELECT文とかのSQLはまず参照するテーブルのlockを取ってからテーブルを呼びにいくわけですが、そのテーブルの中からSQL側が知らない別のテーブルを参照しにいくことができなくなっていた。僕はMySQLの中の人でも開発者でもないので詳しいことはわからないが、作者の気持ちを考えなさいといわれるならば、これはおそらく、いままでは一貫性に問題のある使い方もすることができたけどこれからはAPIとしてはそういう使い方はしないでねってメッセージだと僕は思いました。

時間がなかったので発表のデモではかなり強引な方法で回避しているし、もともとやりたかったことの1割ほども実現できていないので、またやる気が出たタイミングでがんばりたいと思います。ぜんぜん作りかえちゃってもいいのでpullreqウェルカムです。

おわりに

@++, Oracle++
そして @++ (たい焼き的な意味で)

今回はかなり挑戦的なイベント運営でしたが、入れなかったひとが 1人だけど言う奇跡的な流れでした。

ただし、やはり水曜というだけあって飲みに行く人がぜんぜんいなくて、いろいろ話しできなかったのが残念やも!

というわけで、次回は @ さんの成果報告を楽しみにしております。

SEE ALSO

にひりずむ::しんぷる - MySQL Casual #04 で mysqlenv 作った的な話をしてきました

鎌倉幕府の年号が変わっていた

参考

簡単に手元でHTTPのファイルサーバ立てる方法

.zshrcstatic_httpdって関数つくってる。

dotfiles/.zshrc at master · kamipo/dotfiles · GitHub

function static_httpd {
  if type plackup > /dev/null; then
    plackup -MPlack::App::Directory -e 'Plack::App::Directory->new(root => ".")->to_app'
  elif type ruby > /dev/null; then
    if ruby -v | grep -qm1 'ruby 2\.'; then
      ruby -run -e httpd -- --port=5000 .
    else
      ruby -rwebrick -e 'WEBrick::HTTPServer.new(:Port => 5000, :DocumentRoot => ".").start'
    fi
  elif type python > /dev/null; then
    if python -V 2>&1 | grep -qm1 'Python 3\.'; then
      python -m http.server 5000
    else
      python -m SimpleHTTPServer 5000
    fi
  elif type node > /dev/null; then
    node -e "var c=require('connect'), d=process.env.PWD; c().use(c.logger()).use(c.static(d)).use(c.directory(d)).listen(5000);"
  elif type php > /dev/null && php -v | grep -qm1 'PHP 5\.[45]\.'; then
    php -S 0.0.0.0:5000
  elif type erl > /dev/null; then
    erl -eval 'inets:start(), inets:start(httpd, [{server_name, "httpd"}, {server_root, "."}, {document_root, "."}, {port, 5000}])'
  fi
}

むかしはplackupだけ書いてたんだけど、あんまりPerlつかってなかった時期にPlack入れてるかどうか自信ないとすぐにHTTPD上げれないから、そのときにとりあえずHTTPD上げれそうなやつ調べて全部書いておいた。

この中だとRubyPythonが標準モジュールだけでディレクトリインデックス表示できる。

追記

Python3ではSimpleHTTPServerがなくなってhttp.serverになっているそうなので、python2かpython3かを.zshrcに追加しておきました!

    if python -V 2>&1 | grep -qm1 'Python 3\.'; then
      python -m http.server 5000
    else
      python -m SimpleHTTPServer 5000
    fi

追記おわり。

Perlはディレクトリインデックス表示だとPlackPlack::App::Directory入れてないといけないけど、Perlは標準モジュールが貧弱なんでPerlでWeb開発してる人は必ず入れてるからまあよしとします。

PHPは5.4以降のbuilt-in web serverが使えるけどディレクトリインデックスは表示できなかった。

あとNodeも試したんだけど、まずconnect入れないとワンライナーじゃ無理そうなのと、カレントディレクトリをドキュメントルートにできなくてサブディレクトリにしないといけなかったので含めなかった。こんな感じ。

node -e "var connect=require('connect'); connect().use(connect.static('public')).use(connect.logger()).listen(5000);"
追記

@process.env.PWDでフルパス指定すればいけることを教えてもらいました!__dirnameは試したんだけどワンライナーだと'.'になってダメで諦めてた…。ディレクトリインデックスがかっこよかった。

node -e "var c=require('connect'), d=process.env.PWD; c().use(c.logger()).use(c.static(d)).use(c.directory(d)).listen(5000);"

追記おわり。

あとErlangはちょっとやってみたかっただけのオマケです。

MySQL 5.6 で Q4M を動かしたい

一晩がんばってみたけどこれ以上は僕の力量では解決方法がわからないので誰か続きをお願いします…!

kamipo/q4m at mysql-5.6 · GitHub

とりあえずビルドが通ってlibqueue_engine.soまではできあがるんだけど、INSTALL PLUGIN queue SONAME 'libqueue_engine.so'してみるとSymbol not foundでいけてない感じです。

追記

#define DBUG_OFF でだいぶいい感じになりました!あとは僕か OSX の問題かもしれません!!

MySQL 5.6.10 on OSX

% ~/opt/mysql/5.6.10/bin/mysql -u root -v < support-files/install.sql
--------------
INSTALL PLUGIN queue SONAME 'libqueue_engine.so'
--------------

ERROR 1126 (HY000) at line 1: Can't open shared library '/Users/kamipo/opt/mysql/5.6.10/lib/plugin/libqueue_engine.so' (errno: 2 dlopen(/Users/kamipo/opt/mysql/5.6.10/lib/plugin/libqueue_engine.so, 2): Symbol not found: __Z20build_table_filenamePcmPKcS1_S1_)

MySQL 5.5.30 on OSX

% ~/opt/mysql/5.5.30/bin/mysql -u root -v < support-files/install.sql
--------------
INSTALL PLUGIN queue SONAME 'libqueue_engine.so'
--------------

ERROR 1126 (HY000) at line 1: Can't open shared library '/Users/kamipo/opt/mysql/5.5.30/lib/plugin/libqueue_engine.so' (errno: 2 dlopen(/Users/kamipo/opt/mysql/5.5.30/lib/plugin/libqueue_engine.so, 2): Symbol not found: __db_enter_
  Referenced from: /Users)

MySQL 5.6.10 on Ubuntu 12.04 LTS

% ~/opt/mysql/5.6.10/bin/mysql -u root -v < support-files/install.sql
--------------
INSTALL PLUGIN queue SONAME 'libqueue_engine.so'
--------------

ERROR 1126 (HY000) at line 1: Can't open shared library '/home/kamipo/opt/mysql/5.6.10/lib/plugin/libqueue_engine.so' (errno: 2 /home/kamipo/opt/mysql/5.6.10/lib/plugin/libqueue_engine.so: undefined symbol: _db_pargs_)

MySQL 5.5.30 on Ubuntu 12.04 LTS

% ~/opt/mysql/5.5.30/bin/mysql -u root -v < support-files/install.sql
--------------
INSTALL PLUGIN queue SONAME 'libqueue_engine.so'
--------------

ERROR 1126 (HY000) at line 1: Can't open shared library '/home/kamipo/opt/mysql/5.5.30/lib/plugin/libqueue_engine.so' (errno: 2 /home/kamipo/opt/mysql/5.5.30/lib/plugin/libqueue_engine.so: undefined symbol: _db_enter_)