SEEDS Creator's Blog

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

MySQL5.6にしていくつかのSQLでエラーが出るようになった

MySQL5.6にしていくつかのSQLでエラーが出るようになっちゃいました。

具体的にはINSERT文を実行した時、以下のようなエラーとなり処理が実行されなくなりました

SQLSTATE[HY000]: General error: 1364 Field 'hoge' doesn't have a default value

エラー文からデフォルトバリューが設定されてないカラムにNULLを入れようとした為のエラーのようです。 ぐぐるとずばりな回答をされてるブログが見つかりました。

iをgに変えるとorangeになることに気づいたoranieの日記 MySQL5.6で今までのVerでは問題無かったSQL文がエラーになった場合の対処法 http://d.hatena.ne.jp/oranie/20130402/1364906656

日々の覚書 MySQL5.6が勝手にsql_modeを書き換えてくれる話 http://yoku0825.blogspot.jp/2013/03/mysql56sqlmode.html

対処法

sql_modeの設定がMySQL5.5と5.6で異なる事が原因です。 sql_modeのSTRICT_TRANS_TABLESをはずせば、MySQL5.5と同じ動作となる為、 適切と判断した値を勝手に挿入して、警告を出力するだけにとどまり、上記エラーはおきません

mysql> SELECT @@GLOBAL.sql_mode;
+--------------------------------------------+
| @@GLOBAL.sql_mode                          |
+--------------------------------------------+
| STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |
+--------------------------------------------+
1 row in set (0.00 sec)

mysql> SET @@GLOBAL.sql_mode='';
Query OK, 0 rows affected (0.04 sec)

mysql> SELECT @@GLOBAL.sql_mode;
+-------------------+
| @@GLOBAL.sql_mode |
+-------------------+
|                   |
+-------------------+
1 row in set (0.00 sec)

上記だと再起動すると設定が戻ってしまうのでmy.cnfの設定を変更する必要があるのですが注意が必要なのは、mysql5.6から「scripts/mysql_install_db」を実行した場合にMySQLのbasedirにmy.cnfを自動的に作成してくる事です。 このmy.cnfには以下のようなsql_modeが設定されていますので値を空に変更します。

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
↓
sql_mode=''

/etc/my.cnfなど、他のmy.cnfを普段使用している場合、こちら設定してもbasedirのmy.cnfが設定を上書きしてくる為、必ず確認が必要です。(はまりました)

sql_mode STRICT_TRANS_TABLES

sql_modeは公式には以下のようにかかれています。

SQL モード - http://dev.mysql.com/doc/refman/5.1/ja/server-sql-mode.html

SQL シンタックスを MySQL がサポートし、どのようなデータ バリデーション チェックを実行するべきかを定義するもの

mysql5.6で設定されているsql_modeのSTRICT_TRANS_TABLESは通称「ストリクトモード」と呼ばれているもので、無効なデータなどの挿入、更新時にエラーを発生させるモードです。

まとめ

mysql5.6からbasedirに作られるmy.cnfでsql_modeをストリクトモードとして動かすSTRICT_TRANS_TABLESが設定されている。

今後、新規につくるサービスなどであればデフォルト通り有効にする事が望ましいと思いますが、すでに運用しているMySQL5.5のサービスを5.6にアップグレードする場合などは上記のようにSTRICT_TRANS_TABLESをはずせばOKです。