Subscribed unsubscribe Subscribe Subscribe

さくらのPHPでLOAD DATA INFILE使うと#2027: Malformed packetが出る問題について

同じエラーにはまった人が検索でここに辿り着けるように、メモ。

さくらインターネットのサーバーから、
CSVファイルをLOAD DATA INFILEするために、以下のPHPスクリプトを作りました。

<?php
$s = mysql_connect('mysqlxxx.db.sakura.ne.jp', 'user', 'password', true, 128); 
mysql_select_db("user", $s); 

$sql = "LOAD DATA LOCAL INFILE '/home/user/www/File.csv' REPLACE 
      INTO TABLE `ItemInfo` FIELDS TERMINATED BY ','""; 
$query = mysql_query($sql); 
?>

私のサーバーでは『2027: Malformed packet』エラーが出ましたが、
友人*1のさくらサーバー上では、処理に成功しました。
(私のサーバーのDBのバージョンは5で、友人が4です。)


友人のさくらサーバーでは処理に成功したことから、
私のサーバーで出た2027: Malformed packetエラーの原因はCSVファイルの形式等ではなく
もっと基幹的な部分にあるとおもうのですが、
どなたか、原因・解決法をご教授いただきたいです。

さくらインターネットのサーバーから、 CSVファイルをLOAD DATA .. - 人力検索はてな

CSV文字コードや区切りの文字を変えてみたり、CSVの中身を少なくしてみたり全部英語にするなど試してみたが、うまくいかず。
そんな中、たまたまPHP:PHPからMYSQLへデータをインポートする - ウェブサイトの技術っておもしろいよねにあったmysqlimportを使う方法を試してみたところ、成功。

<?php
$strimport = 'mysqlimport
              --host=mysqlxxx.db.sakura.ne.jp
              --user=user
              --password=password
              --local
              --replace
              --fields-terminated-by=","
              DBname /home/user/www/File.csv
             ';
system($strimport);
?>

MySQL :: MySQL 5.1 リファレンスマニュアル :: 12.2.5 LOAD DATA INFILE 構文


Cside_LOAD DATA INFILEをmysqlimportで代用したら成功した。link
Cside_MySQLクイック・リファレンス http://bit.ly/QXe87http://bit.ly/bZ5frY MySQL < Wiki | さくらのレンタルサーバ非公式FAQでも、ファイルからテーブルへのデータ読み込みはmysqlimportと書かれていたし、link
Cside_テーブルへのファイルのデータのインポートはLOAD DATA INFILEでなくmysqlimportが定石ということか? しかしそれなら何故shakさんのサーバーでは実行に成功したのだろう。謎。link
Cside_しかしひとまず、障壁を突破まではいかずとも避けて通ることに成功はしたので、良かった。link


さくらのレンタルサーバ非公式FAQMySQLクイック・リファレンスでも、ファイルからテーブルにデータを読み込む方法がLOAD DATA INFILEでなくmysqlimportと記されていた*2

テキストファイルからデータを取り込むmysqlimportコマンド

ファイル名(拡張子は無視)と同じ名前のテーブルに、データをインポートします。mysqldumpコマンドで出力した.txtファイルや、エディタで編集したタブ区切りのデータをインポートできます。

テキストファイルからデータを取り込む

$ mysqlimport [options] データベース名 ファイル名1 [ファイル名2 ....]
MySQLクイック・リファレンス

TELNET/SSHから使用するには?

通常のMySQLコマンド使用可能。

  • [コンソール] mysql --host=mysql?.db.sakura.ne.jp --user=account --password=dbpassword
  • [CSVインポート] mysqlimport --host=mysql?.db.sakura.ne.jp --user=account --password=dbpassword --local --replace --fields-terminated-by=',' --fields-enclosed-by='"' dbname CSV_filename
  • [バックアップ] mysqldump --host=mysql?.db.sakura.ne.jp --user=account --password=dbpassword dbname > out_filename

MySQL - データベースについて

ので、mysqlimportが定石なのかもしれない。
(自分が手元において参考にしている基礎からのMySQL [基礎からのシリーズ] (プログラマの種シリーズ)では、ファイルからテーブルにデータを読み込む方法はLOAD DATA INFILEと書いてあったので、それを信頼して今までずっとLOAD DATA INFILEでやっていた。)


解説書籍に載っているような方法と、実際に使用している環境で使える方法とはズレがあるのだなと感じた。
今後、「解説書籍に載ってる方法なのに、実行がうまくいかない」という場合は、さくらのレンタルサーバ非公式FAQを中心に参照して、推奨されてる方法を確認していきたい。

*1:shakさんにCSVを送って試していただきました。ご協力本当にありがとうございました。

*2:後者はsshからの使用方法だけど