Skip to content


MySQL 5.6 и sql_mode

После переезда с версии MySQL 5.5.13 на 5.6.10 стали вылезать странные грабли.

Симптом №1:

  1. Caused by: java.sql.SQLException: Incorrect string value: '\xE6\xAF\x94FOX...' for column 'parameter_value' at row 4
  2.         at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078)
  3.         at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4190)

Симптом №2:

  1. Data truncation: Data too long for column 'channel' at row 1
  2. org.hibernate.exception.DataException: could not execute native bulk manipulation query

Так как "раньше всё работало" и в код приложения никто изменений не вносил, закралось подозрение, что новый mysql работает в каком-то более строгом режиме. Гугление вывело на глобальную переменную sql_mode.

  1. mysql> SHOW global variables LIKE 'sql_mode';
  2. +--------------------------+--------------------------------------------+
  3. | Variable_name            | Value                                      |
  4. +--------------------------+--------------------------------------------+
  5. | sql_mode                 | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |
  6. +--------------------------+--------------------------------------------+

Читаем официальное руководство и видим:

STRICT_TRANS_TABLES
If a value could not be inserted as given into a transactional table, abort the statement. For a nontransactional table, abort the statement if the value occurs in a single-row statement or the first row of a multiple-row statement.

На основе этой инфы приходит в голову мысль, что надо этот режим STRICT_TRANS_TABLES попробовать отключить:

  1. mysql> SET GLOBAL sql_mode = 'NO_ENGINE_SUBSTITUTION';
  2.  
  3. mysql> SHOW global variables LIKE 'sql_mode';
  4. +---------------+------------------------+
  5. | Variable_name | Value                  |
  6. +---------------+------------------------+
  7. | sql_mode      | NO_ENGINE_SUBSTITUTION |
  8. +---------------+------------------------+

И таки да, после этого запросы, ранее выполнявшиеся с ошибками, стали отрабатывать нормально, как и было на версии 5.5.13. Чтобы сохранить изменения навсегда, в /etc/my.cnf я добавил в секции [mysqld]

  1. sql-mode="NO_ENGINE_SUBSTITUTION"

Однако далее меня ждала еще одна засада – после рестарта mysql-сервера я опять увидел знакомую картину, несмотря на внесенные в /etc/my.cnf изменения:

  1. mysql> show global variables like 'sql_mode';
  2. +--------------------------+--------------------------------------------+
  3. | Variable_name            | Value                                      |
  4. +--------------------------+--------------------------------------------+
  5. | sql_mode                 | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |
  6. +--------------------------+--------------------------------------------+

Это было непостижимо и удивительно. Я уже и еще раз проверил hostname у сервера, дабы убедиться, что всё ранее сделанное происходило именно на том сервере, где и должно было происходить. Почесав пару минут репу, решил проверить наличие других конфигов mysql-сервера в системе. И таки нашёл один такой в /usr/my.cnf:

  1. $ cat /usr/my.cnf | grep -vE "^#" | sed -r "/^$/ d"
  2. sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

Вот он, вражеский конфиг, который переопределял моё значение sql_mode! Что самое прикольное, больше ничего в этом конфиге не было. Как будто его специально всунули, чтобы добавить мне головняка. После удаления файла /usr/my.cnf и рестарта mysql-сервера я уже раз и навсегда получил возможность наслаждаться значением sql_mode без STRICT_TRANS_TABLES.

Размещено в категории Howto. Теги: .

Комментариев: 3

Чтобы быть всегда в курсе здесь происходящего, Вы можете подписаться на RSS feed для комментариев на эту заметку.

  1. Сергей said

    Спасибо. Столкнулся с такой же проблемой. MySQL 5.5 ставилась с пустым 'sql_mode', а тут переехал на новый сервер, решил 5.6 установить, упс, полезли ошибки там где их не было.

  2. Umka said

    А нельзя никак это остановить на уровне команды mysql? А то у меня стоит МариаДб а там конфиг файл запихнут куда то не могу найти(((

  3. Admin said

    Так написано же как "на уровне команды" - SET GLOBAL sql_mode = 'NO_ENGINE_SUBSTITUTION';

Some HTML is OK

(required)

(required, but never shared)

, или ответить через trackback.

Страница 1 из 11