TL;DR
【2020/02/18 14:23】
MySQL 8.0.19とそれ以降ではエラーメッセージが "Error Code: 3948. Loading local data is disabled; this must be enabled on both the client and server sides" に変わりました(それ以前は "ERROR 1148 (42000): The used command is not allowed with this MySQL version" )
エラーメッセージの出力例以外はこの記事の内容そのままで対処できると思います。たぶん。
--local-infile
のデフォルトが0になったので明示的に1を指定してやる必要があるmysqld
,mysql
コマンドラインクライアント それぞれ別に--local-infile
オプションを持っているので、両方1に指定しないとダメ。- MySQL :: MySQL 8.0 Reference Manual :: 6.1.6 Security Issues with LOAD DATA LOCAL
吊るしのMySQL 8.0で
mysql
コマンドラインクライアントから LOAD DATA LOCAL INFILE
を実行すると転けます。mysql80 125> LOAD DATA LOCAL INFILE '/tmp/aaa' INTO TABLE t1;
ERROR 1148 (42000): The used command is not allowed with this MySQL version
LODA DATA LOCAL INFILE
を実行するには2つの条件が必要で、LOAD DATA LOCAL INFILE
を実行するコネクションにCLIENT_LOCAL_FILES
ケーパビリティー(オプションだと思って)が設定されていること- サーバー側で
opt_local_infile
が設定されていること
2.
は mysqld
の local_infile オプションなのでわかりやすい。単にデフォルトが5.7とそれ以前の “1” から8.0では “0” に変わったというだけ。再起動しなくても
SET GLOBAL
や SET PERSIST
で設定できる。mysql80 125> SELECT @@local_infile;
+----------------+
| @@local_infile |
+----------------+
| 0 |
+----------------+
1 row in set (0.00 sec)
mysql80 125> SET PERSIST local_infile= 1;
Query OK, 0 rows affected (0.00 sec)
mysql80 125> SELECT @@local_infile;
+----------------+
| @@local_infile |
+----------------+
| 1 |
+----------------+
1 row in set (0.00 sec)
サーバー側(
同じエラーなので見分けにくい。
2.
)だけ満たされていても、コネクションに CLIENT_LOCAL_FILES
ケーパビリティー( 1.
)はついてないのでやっぱり転ける。同じエラーなので見分けにくい。
mysql80 125> LOAD DATA LOCAL INFILE '/tmp/aaa' INTO TABLE t1;
ERROR 1148 (42000): The used command is not allowed with this MySQL version
1.
が満たされているかどうかをgdbを使わずに確かめる方法が見当たらなかったのだけれど、 mysql
コマンドラインクライアントであれば —local-infile オプションを有効にするとこのケーパビリティーのフラグが立つ。ただし接続しながら変えることはできないのでこっちは切断してから再接続する。$ mysql80 --local-infile=1
mysql80> use d1
mysql80 132> LOAD DATA LOCAL INFILE '/tmp/md5' INTO TABLE t1;
サーバーサイドのlocal_infileとクライアントサイドのlocal_infileがそれぞれ別で、それぞれ暗黙のデフォルトが0になったから両方で指定しないといけないよ、というお話でした
ちなみにConnector/Cなら
mysql_real_connect
を呼ぶときに client_flag
に CLIENT_LOCAL_FILES
を立てるか、 mysql_options
で MYSQL_OPT_LOCAL_INFILE
を有効にしてやればおk。