mysql:16189
From: HIRATSUKA Sadao <HIRATSUKA Sadao <sh2@xxxxxxxxxx>>
Date: Mon, 15 Dec 2014 21:20:51 +0900
Subject: [mysql 16189] Re: 高速に「INTO OUTFILE → File.Delete → 繰り返し」でエラー(already exists:1086)となります。
こんばんは、平塚です。 以下のような機能と関係あるでしょうか。 Windows の クライアントから SMB 2.0 の通信で、 共有フォルダに作成したファイルへのアクセスがエラーになる場合がある: http://support.microsoft.com/kb/2467179/ja | クライアント サーバー間で SMB 2.0 のセッションが確立されると、 | クライアントはローカルのキャッシュを利用し、このクライアント側の | キャッシュ内容は、デフォルト値では 10 秒おきにサーバーと同期 | されます。このため、サーバー側で新しいファイルが作成されても、 | クライアント側のキャッシュが同期されるまでは、そのファイルへの | 操作が失敗します。 試しにSleepを11秒挟んでみるとか、あるいは ファイル削除をFile.Delete(UNC Path)ではなく、 $ ssh host 'rm /path/to/outfile' (Linuxの例) のように別の手段で実行してみると何か分かるかもしれません。 2014年12月15日 18:32 yoku ts. <yoku0825@xxxxxxxxxx>: > 志澤さん > こんにちは、yoku0825といいます。 > > サンプルコードありがとうございます。 > > サンプルの中ではtestFullPath_Out(UNC記法)と > testFullPathI_IN(ローカルファイル)がありますが、 > 実際にはCIFS経由でやっていたりしますか? > (であれば、実際にファイルが作成されるタイミングはホストしているサーバー側に隠蔽されるので、 > そういうことが起きても不思議がないかなあと思いつつ) > >> →INTO OUTFILEは、対象がなくともファイルを生成するので、 >> 出現するまでWhileで待ってからFile.Deleteを行う。等 > INTO OUTFILEの内部動作は、 > 1. まずファイルが作られる > 2. 行をフェッチする > 3. フェッチした行はバッファにためられる > 4. どこかのタイミングでバッファをfdにフラッシュ > となっていたので、 > ファイルの出現タイミングが2.〜4.のどこかにズレているのだとしたら、 > それはFSかOSかそのへんに欺かれているんじゃないかなぁと思います。 > > Console.WriteLineのあたりか、 > System.IO.File.Existsの *直前* あたりに > sync()に相当する何かを押し込めると幸せになれるんじゃないかと期待しています。。 > > > yoku0825, > > > 2014年12月15日 15:57 志澤 敦 <atsushi.shizawa@xxxxxxxxxx>: >> >> yoku0825さん >> お返事有り難うございました。 >> >> スタックトレースは未だ行なっていませんが、 >> 実行しているのは、C#ですがこの様なフローとなります。 >> 恐らくは、yoku0825さんのイメージ頂いているフローではないか。と考えます。 >> >> 毎回発生する訳ではない辺り、 >> MySQLではなく、Connectorとファイルシステムとの相関によるものでは。 >> との推察が付いたのですが、手詰まりとなりました、、。 >> >> 無理やり機能させるなら、 >> while(File.Exists())等で待機させれば出来なくも無いですが、 >> それも違うな。と言う事で引き続き解決策を検討している所です。 >> →INTO OUTFILEは、対象がなくともファイルを生成するので、 >> 出現するまでWhileで待ってからFile.Deleteを行う。等 >> →しかしながら、.NETのFile.Deleteはスレッドセーフなので、 >> やはりConnector側!?と、堂々巡りに陥ってます。 >> >> ------------------------------------ >> using System; >> using System.Windows.Forms; >> using MySql.Data.MySqlClient; >> >> private void test_ctrl() >> { >> string host = "host_name"; >> string user = "userID"; >> string pass = "password"; >> string schema = "mysql"; >> string conString = "SERVER=" + host + ";" >> + "DATABASE=" + schema + ";" >> + "UID=" + user + ";" >> + "PASSWORD=" + pass + ";"; >> MySqlConnection myConnect = new MySqlConnection(conString); >> myConnect.Open(); >> >> string testDir = @"\\" + host + @"\TEST\"; >> string testFileName = "test.tsv"; >> string testFullPath_Out = System.IO.Path.Combine(testDir, >> testFileName); >> string testFullPathI_IN = @"D:\\TEST\\" + testFileName; >> string SQL = @"SELECT * FROM mysql.db LIMIT 1" >> + " INTO OUTFILE '" + testFullPathI_IN + @"' >> FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\r\n'"; >> for (int i = 0; i < 1000; i++) >> { >> if (System.IO.File.Exists(testFullPath_Out)) >> { >> System.IO.File.Delete(testFullPath_Out); >> } >> using (MySqlCommand myCommand = new MySqlCommand(SQL, >> myConnect)) >> { >> try >> { >> myCommand.ExecuteNonQuery(); >> } >> catch (MySqlException myEx) >> { >> MessageBox.Show(myEx.ToString()); >> //100回に数回レベルでここに到達し、「Already Exists」が発生 >> } >> myCommand.Dispose(); >> } >> Console.WriteLine(i.ToString()); >> } >> MessageBox.Show("正常終了"); >> myConnect.Close(); >> myConnect.Dispose(); >> >> } >> >> (2014/12/14 23:35), yoku ts. wrote: >> >> こんばんは、yoku0825といいます。 >> >> 原因ぽいものは全くわからないのですが、 >> >> > ---検証内容--- >> > ・VS2012でのデバッグ時に、ステップ実行でも発生。 >> > ・File.Delete→INTO OUTFILEの間に、Sleepを5秒挟んだりしても発生する。 >> >> これは ファイルが存在している(?)にも拘わらずFile.ExistsがTRUEで抜けてくるのが問題だと思うので、 >> スリープを挟むとしたらINTO OUTFILEとFile.Delete(File.Exists)の間がいいのでははないでしょうか? >> >> 1. ファイルの存在チェック >> 2. 存在したら消す >> 3. SELECT .. INTO OUTFILE .. >> -- ここでブレーク -- >> 4. ファイルの存在チェック >> 5. 存在したら消す >> 6. SELECT .. INTO OUTFILE .. >> >> ブレークした時に、OSから見てもファイルが存在するのにFile.ExistsがFALSEになるのであれば >> オブジェクトを使いまわしていないか(File.DeleteしたあとのFileオブジェクトが何を返すのかとか)とか、 >> OSから見てファイルがまだ存在しないのなら、mysqldのスタックなど見てみるといいのかもしれません。 >> 5.0も5.6もselect_export::prepareの割と早い段階でcreate_fileを呼んで(ファイルだ >> け先行して作成される)いるので、 >> そこは変わらないような気がするのですが。。 >> >> >> yoku0825, >> >> >> 2014年12月12日 14:22 志澤 敦 <atsushi.shizawa@xxxxxxxxxx>: >>> >>> 志澤と申します。 >>> 初めて投稿させて頂きます。 >>> >>> MySQLWindowsのケースは少ないかとも思いますが、 >>> お心あたり御座いましたら、ご頂けると幸いです。 >>> >>> ---環境--- >>> OS :Windows2012 Std(Memory24GB) >>> DB :MySQL 5.6.21 >>> Coccector :Net 6.9.5 >>> FrameWork :.NET FrameWork 4.5 >>> IDE :VS2012 Pro >>> >>> ---事象--- >>> ・同一ファイルパスにおいて、INTO OUTFILE →File.Deleteを高速に行うと、 >>> IF(File.Exists==TRUE){File.Delete}が機能せず、 >>> SQL発行時にMySqlExceptionが発生。 >>> >>> ・エラー内容は、「1086:already exists」 >>> >>> ・その際、OS上にもファイルは残っており、通常のファイルとして読み書きが出 来る状態。 >>> >>> ---検証内容--- >>> ・VS2012でのデバッグ時に、ステップ実行でも発生。 >>> ・File.Delete→INTO OUTFILEの間に、Sleepを5秒挟んだりしても発生する。 >>> ・Win2008R2でも同様に発生。 >>> ・CentOSでも同様に発生。 >>> ・MySQL5.5でも同様に発生。 >>> --例外事象-- >>> ・MySQL5.0では発生しない。 >>> >>> >>> 以上となります。 >>> DBというより、ConnectorやOS由来な気もしておりますが、 >>> 何か情報御座いましたら、ご助言の程を何卒お願い致します。 >>> >> > -- 平塚貞夫 <sh2@xxxxxxxxxx>
16185 2014-12-12 14:22 [志澤 敦 <atsushi.shi] 高速に「INTO OUTFILE → File.Delete → 繰り返し」でエラー(already exists:1086)となります。 @ 16186 2014-12-14 23:35 ┗["yoku ts." <yoku0825] Re: [mysql 16185] 高速に「INTO OUTFILE → File.Delete → 繰り返し」でエラー(already exists:1086)となります。 @ 16187 2014-12-15 15:57 ┗[志澤 敦 <atsushi.shi] Re: 高速に「INTO OUTFILE → File.Delete → 繰り返し」でエラー(already exists:1086)となります。 @ 16188 2014-12-15 18:32 ┗["yoku ts." <yoku0825] Re: [mysql 16187] Re: 高速に「INTO OUTFILE → File.Delete → 繰り返し」でエラー(already exists:1086)となります。 -> 16189 2014-12-15 21:20 ┗[HIRATSUKA Sadao <sh2] Re: 高速に「INTO OUTFILE → File.Delete → 繰り返し」でエラー(already exists:1086)となります。 16195 2014-12-17 16:58 ┗["atsushi.shizawa" <a]