はじめに
- Dockerコンテナ起動時に発生したエラーの原因と対処法が知りたい
- そもそもMySQLの設定がよくわかっていない
こういった悩みを解決できる記事になっています。
実際僕もError while setting value 'ONLY_FULL_GROUP_BY,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' to 'sql_mode'.
のエラーに遭遇したのですが、この記事の対応で解消できました。
記事の前半ではエラーの発生した状況と原因・解決策を、後半ではこのエラーに関わるMySQLの仕組みを解説します。
最後まで読めばエラーが解消されるだけでなく、その背景まで理解できるかなと思います。
エラー内容
docker-compose.yaml
を作成しdocker-compose up
を実行したところ、Error while setting value 'ONLY_FULL_GROUP_BY,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' to 'sql_mode'.
とエラーが出てしまいました。
エラーログ
go-sample $ docker compose up
[+] Running 12/12
⠿ mysql Pulled 39.1s
⠿ 2c0a233485c3 Pull complete 11.0s
⠿ b746eccf8a0b Pull complete 11.1s
⠿ 570d30cf82c5 Pull complete 11.2s
⠿ c7d84c48f09d Pull complete 11.7s
⠿ e9ecf1ccdd2a Pull complete 11.8s
⠿ 6331406986f7 Pull complete 11.9s
⠿ f93598758d10 Pull complete 15.4s
⠿ 6c136cb242f2 Pull complete 15.5s
⠿ d255d476cd34 Pull complete 30.2s
⠿ dbfe60d9fe24 Pull complete 30.3s
⠿ 9cb9659be67b Pull complete 30.4s
[+] Running 3/3
⠿ Network go-myapi_default Created 0.1s
⠿ Volume "go-myapi_db-volume" Created 0.0s
⠿ Container db-for-go Created 5.3s
Attaching to db-for-go
db-for-go | 2025-01-13 09:35:07+09:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.40-1.el9 started.
db-for-go | 2025-01-13 09:35:07+09:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
db-for-go | command was: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --sql-mode=ONLY_FULL_GROUP_BY,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION --verbose --help --log-bin-index=/tmp/tmp.7Xe1NQl8dv
db-for-go | 2025-01-13T00:35:07.250594Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
db-for-go | 2025-01-13T00:35:07.250705Z 0 [ERROR] [MY-000077] [Server] /usr/sbin/mysqld: Error while setting value 'ONLY_FULL_GROUP_BY,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' to 'sql_mode'.
db-for-go | 2025-01-13T00:35:07.254300Z 0 [ERROR] [MY-010119] [Server] Aborting
db-for-go exited with code 1
このときは以下のdocker-compose.yaml
を使用していました。(コピペしバージョンだけ変更)
version: '3.3'
services:
mysql:
image: mysql:8.0
container_name: db-for-go
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --sql-mode=ONLY_FULL_GROUP_BY,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
environment:
MYSQL_ROOT_USER: ${ROOTUSER}
MYSQL_ROOT_PASSWORD: ${ROOTPASS}
MYSQL_DATABASE: ${DATABASE}
MYSQL_USER: ${USERNAME}
MYSQL_PASSWORD: ${USERPASS}
TZ: 'Asia/Tokyo'
ports:
- "3306:3306"
volumes:
- db-volume:/var/lib/mysql
volumes:
db-volume:
解決策
docker-compose.yaml
からNO_AUTO_CREATE_USER
の記述を削除したところ、コンテナを起動できました。
MySQL5.7には存在しましたが、MySQL8.0からはNO_AUTO_CREATE_USER
が廃止されていたのです。
version: '3.3'
services:
mysql:
image: mysql:8.0
container_name: db-for-go
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --sql-mode=ONLY_FULL_GROUP_BY,NO_ENGINE_SUBSTITUTION # NO_AUTO_CREATE_USER を削除
environment:
MYSQL_ROOT_USER: ${ROOTUSER}
MYSQL_ROOT_PASSWORD: ${ROOTPASS}
MYSQL_DATABASE: ${DATABASE}
MYSQL_USER: ${USERNAME}
MYSQL_PASSWORD: ${USERPASS}
TZ: 'Asia/Tokyo'
ports:
- "3306:3306"
volumes:
- db-volume:/var/lib/mysql
volumes:
db-volume:
これで無事にコンテナを起動できました。
エラーの深掘り
今回のエラーを機にNO_AUTO_CREATE_USER
のことを調べてみました。
興味のある方はご一読ください。
MySQLにおける「ユーザ作成」のしくみ
昔のMySQL(8.0より前)では、SQLのGRANT
で特定の権限を付与する際に、指定したユーザが存在しなければ、自動でユーザ作成する動作をしていました。
たとえば以下はtaro
というユーザにarticles
テーブルのSELECT
権限を付与する例です。
GRANT SELECT ON mydb.articles TO 'taro';
ユーザtaro
が存在しない状態で上記を実行すると、taro
が新規作成されてしまうのです。
ユーザの作成と権限付与を同時に行えるため便利に見えますが、ユーザが意図せず作られたりパスワードが未設定のままになりかねないリスクがありました。
NO_AUTO_CREATE_USER が果たしていた役割
NO_AUTO_CREATE_USER
はGRANT
で自動的にユーザを作成しないようにするための設定です。
有効にしている場合、ユーザが存在しない状態でGRANT
文を発行するとエラーになります。
これにより意図しないユーザ作成を防いでいました。
MySQL8.0でGRANT
によるユーザの自動作成が廃止されたため、それに伴いNO_AUTO_CREATE_USER
も役目を終え、削除されたのです。
NO_AUTO_CREATE_USER
の歴史
- MySQL5.6 以前
GRANT
文でユーザが存在しない場合、自動でユーザが作られる挙動が当たり前。- それを無効化したい場合は
NO_AUTO_CREATE_USER
を指定していた。
- MySQL 5.7
- 「
CREATE USER
でユーザを作成 →GRANT
で権限付与」という明示的な手順を踏む方法を推奨。 - 上記の方針を見据えて
NO_AUTO_CREATE_USER
が非推奨に。
- 「
- MySQL 8.0
GRANT
文で新規ユーザを作る挙動が廃止。- 上記に伴い
NO_AUTO_CREATE_USER
も削除。
まとめ
この記事ではError while setting value 'ONLY_FULL_GROUP_BY,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' to 'sql_mode'.
の原因と対処法をまとめました。
最後に内容をおさらいします。
- MySQL8.0では
NO_AUTO_CREATE_USER
が廃止されているため、設定するとエラーになる。 GRANT
でユーザが自動作成されるのを防ぐため、NO_AUTO_CREATE_USER
が必要だった。- 現在は
GRANT
によるユーザの自動作成が廃止されたため、NO_AUTO_CREATE_USER
も不要となった。
参考になれば幸いです。
コメント