MySQL 8.0でLOAD DATA LOCAL INFILEが "ERROR 1148 (42000): The used command is not allowed with this MySQL version" または "Error: 3948. Loading local data is disabled; this must be enabled on both the client and server sides" で失敗する時 (original) (raw)

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" )

エラーメッセージの出力例以外はこの記事の内容そのままで対処できると思います。たぶん。


吊るしの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つの条件が必要で、

  1. LOAD DATA LOCAL INFILE を実行するコネクションに CLIENT_LOCAL_FILES ケーパビリティー(オプションだと思って)が設定されていること
  2. サーバー側で opt_local_infile が設定されていること

2.mysqldlocal_infile オプションなのでわかりやすい。単にデフォルトが5.7とそれ以前の “1” から8.0では “0” に変わったというだけ。
再起動しなくても SET GLOBALSET 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_flagCLIENT_LOCAL_FILESを立てるか、 mysql_optionsMYSQL_OPT_LOCAL_INFILE を有効にしてやればおk。