タイトル: Exception: Wrong MySQL configuration
SEOタイトル: MySQL Wrong configuration エラーの原因と対処
| この記事の要点 |
|
エラー全体像
Django MySQL バックエンドや Laravel / Rails で接続時に発生する Wrong MySQL configuration 系の総称。具体的なメッセージは以下のように複数パターン:
# Django
django.db.utils.OperationalError: (1067, "Invalid default value for 'created_at'")
django.db.utils.OperationalError: (1366, "Incorrect string value: ...")
ImproperlyConfigured: Error loading MySQLdb module
# Laravel
SQLSTATE[HY000] [2002] No such file or directory
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long
PDOException: SQLSTATE[HY000]: General error: 1709 Index column size too large
# 共通
ERROR 1064 (42000): You have an error in your SQL syntax
ERROR 1273 (HY000): Unknown collation: 'utf8mb4_0900_ai_ci'
原因と対処の早見表
| 症状 | 原因 | 対処 |
|---|---|---|
| Unknown collation: 'utf8mb4_0900_ai_ci' | MySQL 5.7 以前で 8.0 用 collation 指定 | utf8mb4_unicode_ci に変更 |
| Specified key was too long | InnoDB index 767 byte 制限 | Schema::defaultStringLength(191) |
| Incorrect string value | charset 不一致 (絵文字を utf8 に投入) | utf8mb4 化 |
| Invalid default value | Strict Mode + DATETIME のデフォルト 0 | sql_mode 緩和 or 値修正 |
| No such file or directory (2002) | UNIX ソケットパス間違い | DB_HOST=127.0.0.1 に |
| Access denied for user | 権限不足 / パスワード違い | GRANT 再設定 |
| Max connections | max_connections 不足 | my.cnf で増やす |
対処1: charset / collation の統一
もっとも多い罠。MySQL 5.5 まで "utf8" は 3 byte で絵文字が入らず、現代では utf8mb4 (4 byte) が標準:
# /etc/my.cnf or /etc/mysql/my.cnf
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init-connect = 'SET NAMES utf8mb4'
[mysql]
default-character-set = utf8mb4
[client]
default-character-set = utf8mb4
# 反映
# systemctl restart mysql
確認
SHOW VARIABLES LIKE 'character%';
-- character_set_client | utf8mb4
-- character_set_connection | utf8mb4
-- character_set_database | utf8mb4
-- character_set_results | utf8mb4
-- character_set_server | utf8mb4
-- ★ 全部 utf8mb4 になっていること
SHOW VARIABLES LIKE 'collation%';
-- collation_server | utf8mb4_unicode_ci
-- 既存 DB / テーブルの変換
ALTER DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
対処2: Laravel の Specified key was too long
MySQL 5.7 未満 / MariaDB 10.2 未満で InnoDB の index 767 byte 制限に当たります:
// app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Schema;
public function boot(): void
{
// utf8mb4 で 191 * 4 = 764 byte に抑える
Schema::defaultStringLength(191);
}
または MySQL 側で innodb_large_prefix + Barracuda + DYNAMIC を有効化 (5.7+ デフォルト):
[mysqld]
innodb_file_format = Barracuda
innodb_file_per_table = 1
innodb_large_prefix = 1
innodb_default_row_format = DYNAMIC
対処3: Strict Mode 関連エラー
MySQL 5.7+ で厳格モードがデフォルト ON。 ゼロ日付や暗黙的型変換でエラーに:
[mysqld]
# デフォルト sql_mode
sql_mode = STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,
ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,
ERROR_FOR_DIVISION_BY_ZERO
# レガシーアプリで緩めるなら (非推奨)
sql_mode = NO_ENGINE_SUBSTITUTION-- セッション単位で一時的に緩和
SET sql_mode = '';
SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
-- グローバル
SET GLOBAL sql_mode = 'NO_ENGINE_SUBSTITUTION';
-- 確認
SELECT @@sql_mode;
対処4: Django の MySQL 設定
# settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydb',
'USER': 'myuser',
'PASSWORD': '...',
'HOST': '127.0.0.1',
'PORT': '3306',
'OPTIONS': {
'charset': 'utf8mb4',
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
# ★ my.cnf も読ませる場合
'read_default_file': '/etc/mysql/conf.d/django.cnf',
},
'TEST': {
'CHARSET': 'utf8mb4',
'COLLATION': 'utf8mb4_unicode_ci',
},
}
}
対処5: Laravel の error connection 設定
// config/database.php
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'strict' => true,
'engine' => 'InnoDB',
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
my.cnf の場所と読み込み順
| パス | OS / 用途 |
|---|---|
/etc/my.cnf | RHEL / CentOS / Rocky の本体 |
/etc/mysql/my.cnf | Debian / Ubuntu |
/etc/my.cnf.d/*.cnf | RHEL 系 (!includedir で取り込み) |
/etc/mysql/conf.d/*.cnf | Debian 系 |
~/.my.cnf | ユーザ個別 (パスワード保存等) |
$MYSQL_HOME/my.cnf | 環境変数指定 |
読み込み順は mysql --help の末尾で確認できます。後勝ちなので、ディレクトリ配下の追加 conf で上書きできます。
Docker でのマウント
# docker-compose.yml
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: mydb
volumes:
- ./mysql/conf.d:/etc/mysql/conf.d:ro # ★ カスタム設定
- mysql-data:/var/lib/mysql
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --default-authentication-plugin=mysql_native_password
ports:
- "3306:3306"
volumes:
mysql-data:# ./mysql/conf.d/custom.cnf
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
max_allowed_packet = 64M
innodb_buffer_pool_size = 1G
[client]
default-character-set = utf8mb4
権限不足エラー
-- アプリ用ユーザに権限付与
CREATE USER 'myapp'@'%' IDENTIFIED BY 'strongpass';
GRANT ALL PRIVILEGES ON mydb.* TO 'myapp'@'%';
FLUSH PRIVILEGES;
-- 確認
SHOW GRANTS FOR 'myapp'@'%';
-- ホスト指定の罠
-- 'myapp'@'localhost' と 'myapp'@'%' は別ユーザ扱い
SELECT user, host FROM mysql.user WHERE user='myapp';
エラーログの確認
# ログ場所の確認
mysql> SHOW VARIABLES LIKE 'log_error';
# log_error | /var/log/mysql/error.log
# tail で監視
sudo tail -f /var/log/mysql/error.log
# Docker の場合
docker logs -f mysql
# 起動失敗の調査
sudo systemctl status mysql
sudo journalctl -u mysql -n 100
# 設定読み込みの可視化
mysqld --verbose --help | grep -A 1 'Default options'
# Default options are read from the following files in the given order:
# /etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf
FAQ
Q: 設定変更が反映されない
A: systemctl restart mysql で再起動が必要。動的変更 SET GLOBAL は次回再起動で消えるので my.cnf にも書く。
Q: SHOW WARNINGS は何を出す?
A: 直前のクエリの非エラー警告 (暗黙の型変換、データ切り詰め等)。Strict Mode 下では多くがエラーに昇格します。
Q: 設定ファイルの優先順位を確認したい
A: mysqld --verbose --help | head -30 で読み込み順が出力されます。後勝ちなので末尾の方が優先。