Redmine構築後のDBの文字コードをutf8mb4に変換して絵文字に対応する

動機

Redmine上で絵文字を記入し保存しようとすると…

f:id:jackson58:20150519014709p:plain f:id:jackson58:20150519014746p:plain

ゴール

  • 文字コードがutf8で初期化されたDBをutf8mb4に変換し、Redmineで絵文字(4バイト文字)が書き込めるようにする

参考リンク

前提

余談

  • RedmineRails + ActiveRecordなアプリケーションなので、似たような構成ならできるのではないでしょうか。

DBのバックアップ

Redmineを停止する

私の環境ではRedmineはnginx+Passenger上で動いているため、nginxを再起動する。

# service nginx stop

mysqlを停止する

# service mysql stop

データのバックアップ

# cp -rp /var/lib/mysql <バックアップ先>

my.cnfの変更

以下を[mysqld]セクションへ追記。

[mysqld]
character-set-server = utf8mb4
innodb_file_format = Barracuda
innodb_file_per_table = 1
innodb_large_prefix

(innodb_large_prefixオプションによって、後述するキープレフィックスの制限を回避し3072バイトまで拡張できる)

mysqlを起動する

# service mysql start

DB情報を変数にあらかじめ追加する

# MYSQL_DB=db_redmine
# MYSQL_USER=redmine
# MYSQL_PASS=password
# CONVERT_SCRIPT_FILE=convert_script

文字コード変換用スクリプトの作成

# (echo 'alter database `'"$MYSQL_DB"'` default character set utf8mb4;'; mysql -u$MYSQL_USER -p$MYSQL_PASS $MYSQL_DB -e "show tables" --batch --skip-column-names | xargs -I{} echo -e 'alter table `'{}'` ROW_FORMAT=DYNAMIC;\nalter table `'{}'` convert to character set utf8mb4;') > $CONVERT_SCRIPT_FILE

以下のような内容のconvert_scriptファイルが出来ている。

alter database `db_redmine` default character set utf8mb4;
alter table `attachments` ROW_FORMAT=DYNAMIC;
alter table `attachments` convert to character set utf8mb4;
alter table `auth_sources` ROW_FORMAT=DYNAMIC;
alter table `auth_sources` convert to character set utf8mb4;
alter table `boards` ROW_FORMAT=DYNAMIC;
alter table `boards` convert to character set utf8mb4;
...
  • 同じテーブルに対して二度処理を行っているが、それぞれ。
    • 前者(ROW_FORMAT=DYNAMIC)は、MySQL(InnoDB)では、ひとつのカラムのキープレフィックスの最大値が767バイトという制限があり、それを回避するための処理。
    • 後者(convert to...)はテーブルの文字コードを変更する処理。 である。

スクリプトの実行

# mysql -u$MYSQL_USER -p$MYSQL_PASS $MYSQL_DB < $CONVERT_SCRIPT_FILE

エラーが起こらなければOK。

RedmineのDB設定の変更

# vim /path/to/redmine/config/database.yml
encoding: utf8
↓
encoding: utf8mb4

Redmineの再起動

私の環境ではnginx+Passenger上で動いているためnginxを再起動する

# service nginx restart

おしまい

f:id:jackson58:20150519014827p:plain

やはりナウでヤングで積極的でアグレッシブで柔軟でフレキシブルなマインドを持つ若者なので絵文字が使えると落ち着くのである。

thx! id:kuro_m88