All Articles

LOAD DATA INFILE 構文のLOCAL句について

MySQL にデータをインポートするときに少しつまずいたのでメモです.

MySQL にデータをインポートする際,LOAD DATA INFILEを使うと思います.

LOAD DATA INFILE 'path/to/file' TO TABLE 'tablename';

このとき,以下のようなエラーが出て実行できないことがあると思います.

ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

エラーメッセージについてウェブ検索すると,secure-file-privオプションを空値に設定するなどの解決策が見られます. しかし,共用のサーバを使用しているなど,変更できない(変更したくない)場合もあると思います.

この点について,MySQL 公式のドキュメントに次のような記述がありました.

セキュリティー上の理由から、サーバー上にあるテキストファイルを読み取る場合、そのファイルはデータベースディレクトリ内に存在するか、またはすべてのユーザーから読み取り可能のどちらかである必要があります。また、サーバーファイルに対して LOAD DATA INFILE を使用するには、FILE 権限が必要です。(中略)LOCAL 以外のロード操作では、securefilepriv システム変数が空以外のディレクトリ名に設定されている場合、ロードされるファイルはそのディレクトリ内に存在する必要があります。LOCAL を使用すると、クライアントが接続を経由してファイルの内容をサーバーに送信する必要があるため、サーバーが直接ファイルにアクセスできるようにした場合より少し遅くなります。その一方で、ローカルファイルをロードするために FILE 権限は必要ありません。

つまり,

  • LOAD DATA INFILEでは内部的に MySQL がサーバ上のファイルにアクセスを行うため,MySQL に対しサーバ上のファイルにアクセスする権限を与える必要がある.
  • --secure-file-privオプションで指定されたディレクトリ内のファイルに対しては,MySQL はアクセス可能.
  • 一方で,LOAD DATA LOCAL INFILEとすることで,コマンドを実行しているユーザがファイルを MySQL に対して送信するため,MySQL にファイルへのアクセス権限は必要ない

ということであると理解しました.

また,エラー処理に関しても記述がありました.

LOAD DATA INFILE では、データ解釈や重複キーのエラーによって操作が終了します。LOAD DATA LOCAL INFILE では、操作の最中にファイルの転送を停止する方法がサーバーにはないため、データ解釈や重複キーのエラーは警告になり、操作は続行されます。

LOCAL句の指定の有無による違いが理解できていれば,この仕様は理解できますね.

ちなみにこのとき発生した warning は,クエリを実行した直後であれば,SHOW WARNINGS文で確認できます.

以上.MySQL について,また 1 つ賢くなることができました.

参考文献