かみぽわーる

kamipo's blog

簡単に手元で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_)

MySQL の unknown option エラーはオプションに loose- プレフィックスをつけると回避できる

もうMySQL 5.5 GAが出てから1年以上が経ち、つい先日とうとうMySQL 5.6 GAも出た昨今、これから先パーソナルユースでこれより以前のMySQLなど使うことはないだろうと~/.my.cnfを書いていたのだけど、昨日ちょっとしたアレでMySQL 5.1を入れたらMySQLが進化しすぎててオプションコメントアウトしまくらないと動かないわーとかいってたらloose-つけるといいですよって教えてもらった。

これは知らなかった!

MySQL 5.1とか使うことはまぁないだろうけど、いろんなバージョン試してるときに明らかに新しめのオプションにloose-つけとくと便利そう。とりあえず今回は以下のオプションにloose-つけたらいけた。

[mysqld]
loose_innodb_strict_mode
loose_innodb_buffer_pool_instances = 1 
loose_innodb_read_io_threads = 8 
loose_innodb_write_io_threads = 8 
loose_innodb_file_format = Barracuda
loose_innodb_print_all_deadlocks
loose_innodb_large_prefix

あとcharacter_set_server = utf8mb4でこけるのは、オプションはあるけど値が未対応なやつなので、my.cnfのグループをバージョン指定して読み込めるやつを使って回避した。

[mysqld]
character_set_server = utf8mb4

[mysqld-5.1]
character_set_server = utf8

my.cnfのオプション指定は後勝ちなんで、MySQL 5.1のときはutf8、それ以外のときはutf8mb4という感じに指定できます。

あと、最新のMySQLをソースからとりあえず深く考えずにビルドしてみたい向きにはmysql-buildを使うといいらしいです。

参考

#cross2013 に行ってきた

聴いたやつ。

感想など

出張Shibuya.XSSCD-ROMをイジェクトしたくならない人は今すぐ病院に行ってくださいで有名な@さんが登壇されるのを楽しみにしていたんですが、ノロで口からイジェクトしまくって欠席されたみたいで、その記事を書くのをやめて今すぐ病院に行って欲しかったです、残念でした…。

そのはせがわさんが言っていた好きな言葉があって

「その仕様を最も悪用できる方法を思いつくことが世界の平和の貢献につながる」

NetAgent Official Blog : 私がセキュリティの世界に挑戦した理由 ~はせがわようすけ~

僕は世界の平和とまではなかなか言えないのだけど、僕と僕のまわりの平和ぐらいは守りたいし、世の中の悪意から身を守って被害者にならないことで、ささやかながら平和に貢献したいという気持ちではいるので、Shibuya.XSSでは悪用できる便利な仕様をいっぱい知れてほんと勉強になります。

あと昨今は、言いがかりまがいの因縁をつけて炎上されられたり、サービスや会社を潰すまで追い詰められたり、インターネットのサービスをやってるともはや他人ごとではない話なので、malaさんの話はもっと多くの人が興味を持っていい話だと思った。

体系的に学ぶ安全な利用規約の作り方

継続的ほげほげのゲンバのハナシのほうは、おしまい姉妹と負荷分析ミーティングがすごいいいなって思いました。

あと僕は運用の仕事をずっとやってきてたんでそれで思うところは、あんま人間ががんばらなくてよくなるようになればいいなってところで、僕は自分にはできないことができる他の開発者のことを純粋にすごいなと思ってるので、「またこんなクソクエリ書いて…」みたいな小姑のようなことはできるだけ言いたくないし、そういうの言うほうも言われるほうもあまりいい気分にならないだろうし、例えばMySQLとかが

MySQL「何者だ!」 クソクエリ「おならです」 MySQL「よし、通れ!」

みたいなことだから人間がうんこもらすみたいなことになってるわけで、そうすると「僕がみんなのおしりをぬぐう係です」みたいに言ってしまうわけで、こんだけ人間がうんこもらしてる状況なんでもうちょっとミドルウェアとかが安全に使える仕組みになって、あんま人間ががんばらなくてよくなればいいなと思うところです。

そんな感じでした。

MySQL(InnoDB) で "Index column size too large. The maximum column size is 767 bytes." いわれるときの対策

tl;dr: MySQL 5.5.14以降だとinnodb_large_prefixオプションで3072バイトまでインデックス張れる

MySQL(InnoDB)では、ひとつのカラムのキープレフィックスの最大値が767バイトという制限があるので、ついうっかりして

Index column size too large. The maximum column size is 767 bytes.

とか

Specified key was too long; max key length is 767 bytes

といったエラーを見たことある人は多いのではないかと思います。

よくあるケースだと、varchar(256)以上のutf8なカラムにインデックスを張ろうとするとこのエラーとご対面できます。

CREATE TABLE t (c varchar(256), index (c));
ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes.

で、話は変わってもうMySQL 5.5 GAが出てから一年が経ち、MySQL 5.6 GAもそろそろ出るころだし、新規で作るアプリケーションはutf8mb4でいきたいわけじゃないですか。

そこで、Rails(ActiveRecord)をutf8mb4で動かしたいわけなんですが、db:migrateするとしょっぱなからschema_migrationsってテーブルにインデックス張れなくて落ちます。

utf8のときのスキーマはこんなの。

CREATE TABLE `schema_migrations` (
  `version` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  UNIQUE KEY `unique_schema_migrations` (`version`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

ActiveRecordでstring型のカラムを定義すると、MySQLだとvarchar(255)になるので、utf8mb4だとインデックス張ると767バイトを超えてしまう。

で、なんかきれいに解決できる方法ないかなって考えたんだけど、MySQL 5.5.14以降だとinnodb_large_prefixというオプションが追加されてて、キープレフィックスの制限を3072バイトまで拡張できます。

ただし、ROW_FORMATをDYNAMICかCOMPRESSEDにする必要がある(デフォルトはCOMPACT)ので、ActiveRecordのcreate_tableメソッドをちょいと書き換えてデフォルトのROW_FORMATをDYNAMICにすればよさそうなんで、とりあえずそうしてます。

my.cnfに以下を追加して

[mysqld]
innodb_file_format = Barracuda
innodb_file_per_table = 1
innodb_large_prefix

最終的なスキーマはこんなかんじ。

CREATE TABLE `schema_migrations` (
  `version` varchar(255) NOT NULL,
  UNIQUE KEY `unique_schema_migrations` (`version`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC

参考

#isucon2 にて死す

当日を振り返った翌日の感想はコチラ。

今回もチームやすべえとして@くんに熱烈ラブコールを送ってたんですが、当日は飛行機の上ということで振られてしまったので、それぺちの@さんとRails高速化の@さんまったく接点のない二人を誘って参加しました!

二人とも突然の誘いを快く受けてくれてありがとうございました!!

結果はというと、まずクエリのボトルネックをインデックス張ってつぶしたあたりまではよかったんですが、サイドバーのキャッシュの不整合を解決できずDBから引き直そうとしたところで致命的な設計ミスに気づいてしまって、せめて完走させてスコアは出そうってことでgit initした状態に戻してフィニッシュでした。

個人的に力不足だったなと思うところが多くて、優勝したfujiwara組のレポートで、ボトルネックを着実に計測してそれに基づいて施策を打ち出していく、これがベーシックなようで本当にむずかしく、歴然とした実力の差があったんだなと感じました。あとはメンバーそれぞれの役割が分担されてることで、チームとしてより大きな成果につながったんだなというのも感じました。

こういうコンテストで人と競い合うことで、あらためて自分のスキルや他のエンジニアの人たちとの差がわかって、自分はどうなりたいのかとか何ができるようになりたいのかを考えるきっかけになってすごくよかったです。

あとはとにかく楽しかった!仕事でも発揮したことない今年一番の集中力を発揮した!

この気持ちをバネにして次はリベンジ果たしたいですね。