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。
MySQL8.0.11をローカル環境で利用しています。
返信削除質問なのですが、
```
mysql --local-infile=1 -u root -p mydb;
```
でサーバーに入った時に、--local-infile=1が反映されていなく、
設定を見てもlocal_infileがOFFのままで、
`load local data`をしてもエラーになってしまいます。(以下の通り)
```
show global variables like "%infile%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| local_infile | OFF |
+---------------+-------+
1 row in set (0.00 sec)
```
コマンドラインオプションで有効にできないことと
この記事で取り扱っていることは関係があるのでしょうか?
このコマンドラインオプションで`load local data infile`を有効にできなかったため、
結局MySQLサーバーに入って、以下のように直接変数を書き換えて有効にしたら、
`load local data infile`が使えるようになりました。
```
set global local_infile=ON;
```
本当にお時間のある時で良いので、ご返答いただけたら幸いです。
度々失礼いたします。
返信削除コメントしておいて大変申し訳ないのですが、自己解決?しました。
この記事に関しての理解の確認のようなことをさせていただきたいのですが、
以下の2つのSQL文により表示されるものが、サーバー側の`opt_local_infile`の設定(記事中の2番の設定)であり、これを変更することでサーバー側の設定ができる。
```sql
select @@local_infile; -- どちらも同じ意味?
show global varaiables like "%infile%"; -- どちらも同じ意味?
```
terminalからMySQLコマンドラインクライアントに接続する時に付与する
`--local-infile=1`オプション
が、CLIENT_LOCAL_FILES ケーパビリティーの設定である。(クライアント側の設定、これを確かめる方法はない?)
そしてこれら2つの設定がONになっていないと`load data local infile`を行えない。
という理解でよろしいでしょうか?
質問を連投してしまい申し訳ないのですが、教えていただければ幸いです。
長文失礼いたしました。
こんにちはこんにちは。
削除おっしゃっている通りで間違いありません!
> 以下の2つのSQL文により表示されるものがサーバー側の設定ができる。
その通りです!
> terminalからMySQLコマンドラインクライアントに接続する時に(クライアント側の設定、これを確かめる方法はない?)
その通りです!
> そしてこれら2つの設定がONになっていないと`load data local infile`を行えない。
まさにその通りです!