MySQL5.6でSQLSTATE[HY000]: General error: 1364 Field xxx doesn't have a default value with queryが発生する。

MySQL5.6で動作させているプログラムのログを確認していると、SQLSTATE[HY000]: General error: 1364エラーが出ていることに気がついた。

  • mysql
SQLSTATE[HY000]: General error: 1364 Field 'xxx' doesn't have a default value with query:"INSERT INTO ...

xxx Field は確かにデフォルト値を持っていないし、INSERT 文にきちんと値を設定していない。 はて、こんなエラー出てたかな?以前は成功していたような気がする。 調べてみると、

sql_modeにSTRICT_TRANS_TABLESが設定されていることが原因のようだ。 MySQLのVARIABLES を確認してみると、確かにSTRICT_TRANS_TABLESが設定されていた。

  • mysql
SHOW VARIABLES LIKE  'sql_mode';

sql_mode    <strong>STRICT_TRANS_TABLES</strong>,NO_ENGINE_SUBSTITUTION

しかし、同時期に同じ手順(yum)でインストールしたMySQL5.6でMySQLのVARIABLESをチェックしてみるとsql_modeは空っぽだ。

  • mysql
SHOW VARIABLES LIKE  'sql_mode';

sql_mode    

なぜ違うのだろう。仕方ないのでmy.cnfにsql_mode = ‘‘を記載してmysqldを再起動。 しかし、設定が効かない。SHOW VARIABLES LIKE ‘sql_mode’;してもsql_mode STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTIONのままだ。 さらに調べてみると、/usr/my.cnfにそれらしい設定があった。

  • /usr/my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html

[mysqld]

# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M

# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin

# These are commonly set, remove the # and set as required.
# basedir = .....
# datadir = .....
# port = .....
# server_id = .....
# socket = .....

# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
<strong>
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES</strong>

しかしこの/usr/my.cnfは、別のMySQL5.6をインストールしたサーバーには存在しない。 /usr/my.cnfのタイムスタンプをみてみると、最近(昨日)作成されているようだ。

#ls -lc /usr/my.cnf
-rw-r--r-- 1 root root 943 May 12 20:11 /usr/my.cnf

この時間帯にやったことといえば、mysql_install_db。DBがおかしくなったのでダンプして初期化しリストアした。 mysql_install_dbの中身を見てみると、

  • /usr/bin/mysql_install_db
・
・
・
my $config_file;
my $copy_cfg_file;

# ----------------------------------------------------------------------
# This will be the default config file (unless creation is unwanted)
# ----------------------------------------------------------------------

my $cnfext = ( $^O =~ m/^(MSWin32|cygwin)$/ ) ? "ini" : "cnf";

$config_file= "$basedir/my.$cnfext";

my $cfg_template= find_in_basedir($opt,"file","my-default.$cnfext",
                                  ".", "share","share/mysql","support-files");
# Distros might move files
if ((! -r $cfg_template) && (-r "/usr/share/mysql/my-default.cnf")) {
  $cfg_template = "/usr/share/mysql/my-default.cnf";
}

-e $cfg_template or cannot_find_file("my-default.$cnfext");

$copy_cfg_file= $config_file;
my $failed_write_cfg= 0;
if (-e $copy_cfg_file)
{
  $copy_cfg_file =~ s/my.$cnfext/my-new.$cnfext/;
  # Too early to print warning here, the user may not notice
}

if ( ! $keep_my_cnf ) {
  open (TEMPL, $cfg_template) or error($opt, "Could not open config template $cfg_template");
  if (open (CFG, "> $copy_cfg_file")) {
    while (<TEMPL>) {
      # Remove lines beginning with # *** which are template comments
      print CFG $_ unless /^# \*\*\*/;
    }
    close CFG;
  } else {
    warning($opt,"Could not write to config file $copy_cfg_file: $!");
    $failed_write_cfg= 1;
  }
  close TEMPL;
}
・
・
・

mysql_install_dbのスクリプトは、なにやら/usr/share/mysql/my-default.cnfを"$basedir/my.$cnfext"にコピーしている雰囲気だ。 しかも、/usr/share/mysql/my-default.cnfの中身は/usr/my.cnfと同じである。 /usr/my.cnfを削除し、mysqldを再起動したら、クエリエラーが出なくなった。 MySQL5.6以降ではmysql_install_dbをやったあとは/usr/my.cnfを確認したほうが良さそうだ。