docker-compose+MySQL8(8.0.18)で初期データをCSVロードしようとするとエラー(The used command is not allowed with this MySQL version)に
環境情報
- MacOS X 10.15.1(19B88)
- Docker 19.03.5
- MySQL 8.0.18
docker-composeのディレクトリ構成
.
├── docker-compose.yml
└── mysql
├── init
│ ├── 10_ddl.sql
│ └── data.csv
各ファイルの中身
docker-compose.ymlファイルの中身
version: '3'
services:
mysql:
image: mysql:latest
environment:
#イメージの起動時に作成するデータベースの名前
MYSQL_DATABASE: yudb
#このユーザはMYSQL_DATABASE変数で指定されたデータベースに対してスーパーユーザとしての権限(GRANT ALL)を保持する
MYSQL_USER: mysqluser
#MYSQL_USERのパスワード
MYSQL_PASSWORD: MySQLPass00
# MySQLにおけるスーパーユーザであるrootアカウントに設定するためのパスワード
MYSQL_ROOT_PASSWORD: MySQLRootPass00
ports:
- "3306:3306"
volumes:
#- ./mysql/var_lib_mysql:/var/lib/mysql ← 起動するたびにMySQLのデータベースを初期化したいのでコメントアウトしておく
# /docker-entrypoint-initdb.d/配下は、Dockerコンテナが初回起動(初期化)される際に1度だけ実行されるスクリプトなどを配置
# *.sh / *.sql / *.sql.gzの拡張子のファイルはファイル名の昇順に実行される。
- ./mysql/init:/docker-entrypoint-initdb.d
10_ddl.sqlファイルの中身
create table if not exists m_sample(
`code` char(3) not null,
`name` varchar(80) not null,
primary key(`code`)
) engine=innodb default charset=utf8;
LOAD DATA LOCAL INFILE '/docker-entrypoint-initdb.d/data.csv' INTO TABLE yudb.m_sample FIELDS TERMINATED BY ',' ENCLOSED BY '"';
data.csvファイルの中身
"001","test001"
"002","test002"
"003","test003"
"004","test004"
docker-composeでmysqlのコンテナを起動するとエラーが発生
docker-compose up
コマンドを実行してコンテナを起動
$ docker-compose up -d
Creating network "docker-mysql8-err_default" with the default driver
Creating docker-mysql8-err_mysql_1 ... done
docker-compose ps
コマンドを実行して状態を確認
$ docker-compose ps
Name Command State Ports
------------------------------------------------------------------------
docker-mysql8-err_mysql_1 docker-entrypoint.sh mysqld Exit 1
docker-compose logs
コマンドを実行してログを確認
$ docker-compose logs
Attaching to docker-mysql8-err_mysql_1
mysql_1 | 2019-12-10 22:45:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.18-1debian9 started.
mysql_1 | 2019-12-10 22:45:36+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
mysql_1 | 2019-12-10 22:45:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.18-1debian9 started.
mysql_1 | 2019-12-10 22:45:36+00:00 [Note] [Entrypoint]: Initializing database files
mysql_1 | 2019-12-10T22:45:36.889727Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.
mysql_1 | 2019-12-10T22:45:36.889859Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.18) initializing of server in progress as process 44
mysql_1 | 2019-12-10T22:45:38.650792Z 5 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
mysql_1 | 2019-12-10 22:45:42+00:00 [Note] [Entrypoint]: Database files initialized
mysql_1 | 2019-12-10 22:45:42+00:00 [Note] [Entrypoint]: Starting temporary server
mysql_1 | 2019-12-10T22:45:42.613856Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.
mysql_1 | 2019-12-10T22:45:42.614006Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.18) starting as process 93
mysql_1 | 2019-12-10T22:45:43.302666Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
mysql_1 | 2019-12-10T22:45:43.307378Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
mysql_1 | 2019-12-10T22:45:43.342347Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.18' socket: '/var/run/mysqld/mysqld.sock' port: 0 MySQL Community Server - GPL.
mysql_1 | 2019-12-10 22:45:43+00:00 [Note] [Entrypoint]: Temporary server started.
mysql_1 | 2019-12-10T22:45:43.361902Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock'
mysql_1 | Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
mysql_1 | Warning: Unable to load '/usr/share/zoneinfo/leap-seconds.list' as time zone. Skipping it.
mysql_1 | Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
mysql_1 | Warning: Unable to load '/usr/share/zoneinfo/zone1970.tab' as time zone. Skipping it.
mysql_1 | 2019-12-10 22:45:47+00:00 [Note] [Entrypoint]: Creating database yudb
mysql_1 | 2019-12-10 22:45:47+00:00 [Note] [Entrypoint]: Creating user mysqluser
mysql_1 | 2019-12-10 22:45:47+00:00 [Note] [Entrypoint]: Giving user mysqluser access to schema yudb
mysql_1 |
mysql_1 | 2019-12-10 22:45:47+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/10_ddl.sql
mysql_1 | ERROR 1148 (42000) at line 7: The used command is not allowed with this MySQL version
ログを確認すると、ログの最終行に
mysql_1 | ERROR 1148 (42000) at line 7: The used command is not allowed with this MySQL version
というログが出力されていました。
調べてみると、MySQL8以降では、デフォルトのMySQLサーバーのままだとLOAD DATA LOCAL INFILE
によるCSVファイルのロードが出来ないようです。
解決方法
解決するには2つの対応が必要になります。
- 1つはサーバーサイドの設定として
local_infile
システム変数をONにする - もう1つがクライアントから接続する際に
--local-infile[=1]
オプションを指定する
サーバーサイドの設定でlocal_infile
システム変数をON
10_ddl.sql
ファイルに1行追加して以下のように定義する。
LOAD DATA LOCAL INFILEの行はコメントアウトして使えなくしておく。
set global local_infile = 1;
create table if not exists m_sample(
`code` char(3) not null,
`name` varchar(80) not null,
primary key(`code`)
) engine=innodb default charset=utf8;
-- LOAD DATA LOCAL INFILE '/docker-entrypoint-initdb.d/data.csv' INTO TABLE yudb.m_sample FIELDS TERMINATED BY ',' ENCLOSED BY '"';
クライアントから接続する際に--local-infile[=1]
オプションを指定する
これを実現するために、sqlファイルでのロードではなく、shellによるロードへ切り替えることで解消できました。
ディレクトリ構成は以下の通り。
.
├── docker-compose.yml
└── mysql
└── init
├── 10_ddl.sql
├── 20_data_load.sh ← このファイルを追加
└── data.csv
20_data_load.sh
ファイルを追加します。
mysql -uroot -pMySQLRootPass00 --local-infile=1 yudb -e "LOAD DATA LOCAL INFILE '/docker-entrypoint-initdb.d/data.csv' INTO TABLE m_sample FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\n'"
解消したか確認する
docker-compose up -d
を実行後、しばらくしてからdocker-compose ps
を実行すると、今度は正常にMySQLのコンテナが起動していることがわかる。
$ docker-compose up -d
Creating network "docker-mysql8-err_default" with the default driver
Creating docker-mysql8-err_mysql_1 ... done
$ docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------
docker-mysql8-err_mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp, 33060/tcp
念のためロードしたデータがちゃんと入っているかも確認してみる。
$ docker-compose exec mysql bash
root@46a05fff4d72:/#
root@46a05fff4d72:/# mysql -umysqluser -pMySQLPass00
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.18 MySQL Community Server - GPL
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> connect yudb
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Connection id: 9
Current database: yudb
mysql> show tables;
+----------------+
| Tables_in_yudb |
+----------------+
| m_sample |
+----------------+
1 row in set (0.00 sec)
mysql> select * from m_sample;
+------+---------+
| code | name |
+------+---------+
| 001 | test001 |
| 002 | test002 |
| 003 | test003 |
| 004 | test004 |
+------+---------+
4 rows in set (0.00 sec)
とりあえずデータも無事にロードされているので、これでエラーの問題は解消できることがわかりました。