Rails + CircleCI で MySQL の utf8mb4 をつかう

前提

ActiveRecordをutf8mb4で動かす - Qiita

気合でコンテナ上の MySQL の設定を変更する

circle.yml
database:
  override:
    - mysql -u root -e 'set global innodb_file_format = Barracuda'
    - mysql -u root -e 'set global innodb_file_per_table = 1'
    - mysql -u root -e 'set global innodb_large_prefix = 1'
    - bundle exec rake db:create db:schema:load --trace

本当は怖い less

tl;dr

パイプから大きいデータを less に渡すとメモリ死する。

パイプから読むとき

必要に応じて動的にバッファが確保される。起動直後に G とか押すと全部メモリにのる。GB オーダーのファイルでそういうことすると死ぬ。

どうしたらいいの

-B オプションをつかうと、動的にメモリを確保せず 64 KB(Amazon Linux 64bit の場合)または -b オプションで指定されたサイズのみをバッファに使用する。

そもそも

less で GB オーダーのファイル開く意味が分からない。grep とかでしぼってから less に渡そう。

R3/I2 ファミリーで instance store をつかう

tl;dr

起動時にフォーマットしてマウントする。

Amazon Linux のデフォルト

cloud-init によって ephemeral0 が起動時にマウントされる。

$ grep mounts -A1 /etc/cloud/cloud.cfg
mounts:
 - [ ephemeral0, /media/ephemeral0 ]
$ tail -1 /etc/fstab
/dev/sdb        /media/ephemeral0       auto    defaults,nofail,comment=cloudconfig     0       2

R3/I2 ファミリー

SSD をいい感じに使うための TRIM という仕組みに対応していて、その関係で instance store が起動時にフォーマットされない。ので、起動時にマウントされない。 http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html#InstanceStoreTrimSupport

どうするよ

/etc/rc.d/rc.local に以下を追加(cloud-init とかでもいいとおもう)。

if mount | grep '/dev/xvdb' &> /dev/null || [[ $(cat /sys/block/xvdb/queue/discard_max_bytes) -ne 0 ]]; then
  mkfs.ext4 -E nodiscard /dev/xvdb && mount -o discard /dev/xvdb /media/ephemeral0
fi

instance store がマウントされていない且つ TRIM に対応している場合は、instance store をフォーマットしてマウントする。デバイス名はよしなに。

困ったこと

instance store を複数つかう場合に対応していない。