予兆
なんか以前から,EC2のインスタンスにSSHしたときに
-bash: warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or directory
とか言われてなんじゃこりゃってなってたんですが,特に作業に影響ないから放置してました...
なんか変
MySQLの文字コード関係の設定
この状態でサーバ上のMySQLにログインすると,文字コード関係の設定が以下のようになってました.
mysql> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)
こりゃいかんということで,そういえば文字コード関係の警告でてたなぁとか思いながら
export LC_CTYPE=ja_JP.UTF-8
とかやってやると以下のようになったので一安心
mysql> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)
サーバ上でファイルを編集したら文字コードが残念なことに
サーバ上でSQLが書かれたファイルを編集してたんですが,上記の警告が出てる状態で編集したために?ファイルの文字コードがiso-2022-jp-3
とかいう見慣れないものになってしまってました.
起こったこと
MySQLで,ファイルを読みこませてSQLを実行させようとしたところ,エラーでコケた.
mysql> source mask.sql
ERROR 1406 (22001): Data too long for column 'body' at row 6
書かれてたSQLは下記の通り
update foo set body = repeat('*', char_length(body));
やりたいことは,body
カラムの内容を同文字数の*
で置き換えたいだけなのに,なんで溢れるのかがわからない...
-
varchar
って文字数だったっけなーとか -
char_length
って文字数カウントだよなーとか
ただ,MySQLのコンソールで直接SQLをタイプして実行すれば問題なく実行されたことから,あれー??ってなってファイル見直すと文字コードがiso-2022-jp-3
になってましたとさ...
自分は*
(U+FF0A)のつもりで打ってたのに,文字コードの違いにより全く別の文字列と解釈されてしまってMySQLに弾かれていたと...
対応
一番下にある,Environmentの項目
- Set locale variables automatically
が,最初からそうだったのか自分でやったのかよくわからないんですが,チェック済みだったのを外す
そうすると,LC_CTYPE
が未設定の状態になるので,問題が起きなくなりました.
まとめ
警告は無視しちゃいかん.