読者です 読者をやめる 読者になる 読者になる

【開発】utf8mb4のDBを使ったwebアプリケーションをcircleciにパスさせる

f:id:keisuke_ohta:20151023181518p:plain

最近ではCIツールを使っている会社は少なくないと思います。私は仕事でcircleciを使っているのですが、文字コードがutf8mb4のDBを使ったwebアプリケーションをgithubにプッシュしたところ、circleciでエラーが出てしまいました。そこでこの記事では、utf8mb4のDBを使ったwebアプリケーションを、circleciにパスさせる方法をまとめました。

現象

circleciを使ったことのない人のために話すと、circleciをgithubと連携させるとgithubにプッシュするたびにcircleciが走るのですが、circleciにgithubリポジトリを登録してドヤ顔でgithubにプッシュしたところ、デフォルトで設定されているタスクrake db:create db:schema:loadで下記のようなエラーが出ました。

-- add_index("table_name", ["column_name"], {:name=>"index_name", :unique=>true, :using=>:btree})
rake aborted!
ActiveRecord::StatementInvalid: Mysql2::Error: Specified key was too long; max key length is 767 bytes: CREATE UNIQUE INDEX `index_name` USING btree ON `table_name` (`column_name`) 

原因

いろいろネット上で調べてみるとこんなことが書かれてました。

MySQLのencodingがutf8の場合は3バイトのため、255 * 3 = 765バイト で767バイト以下に収まります。 しかし、utf8mb4の場合は4バイトのため、255 * 4 = 1,020 バイトとなり、767バイトを超えてしまうためエラーが発生します。 今回utf8mb4を使用していたため、上記エラーが発生しました。

解決策

これをするとcircleciをパスできました。

  1. circleciの設定を書けるファイル「circleci.yml」をプロジェクトのルートディレクトリに配置
  2. circleci.ymlに下記を記述
dependencies:
  pre:
    - echo '[mysqld]' | sudo sh -c 'cat >>  /etc/mysql/my.cnf'
    - echo 'innodb_file_format=Barracuda' | sudo sh -c 'cat >>  /etc/mysql/my.cnf'
    - echo 'innodb_file_per_table=1' | sudo sh -c 'cat >>  /etc/mysql/my.cnf'
    - echo 'innodb_large_prefix=1' | sudo sh -c 'cat >>  /etc/mysql/my.cnf'
    - sudo service mysql restart

同じようなエラーに直面した人がいたらやってみてください。

参考