web-dev-qa-db-ja.com

Windowsファイル共有:新しく作成されたファイルが一定期間表示されないことがあるのはなぜですか?

私たちは私たちを狂わせるような非常に奇妙な問題に直面しました。 File Share PCで新しく作成されたファイルが、しばらくの間「存在しない」場合がありました。問題を再現するには、少なくとも2台のコンピューターが必要です(alphaおよびbeta)。 beta PC(_\\beta\share\bug_)にファイル共有を作成し、alpha PCからこのPowerShellスクリプトを実行します。

_param(
  $sharePath="\\beta\share\bug"
)
$sharePC = ($sharePath -split '\\')[2]
$session = New-PSSession -ComputerName $sharePC
$counter = 0
while ($true) {
  $fileName = $sharePath + "\$counter.txt"
  Invoke-Command -Session $session -ScriptBlock {
    param(
      $fileName
    )
    "" > $fileName
  } -ArgumentList $fileName
  if (Test-Path $fileName) {
    Write-Host "File $fileName exists" -fore Green
  } else {
    Write-Host "!!! File $fileName does NOT exist!" -fore Red
  }

  $counter = $counter + 1
  Start-Sleep 2
}
_

このスクリプトを開始すると、次のメッセージが表示されるはずです。

_File \\beta\share\bug\1.txt exists
File \\beta\share\bug\2.txt exists
...
_

そして今:_cmd.exe_を開き、次のコマンドを実行します:

_if exist \\beta\share\bug\foo.txt echo 1_

この後、約10秒間、次のメッセージが表示されます。

_!!! File \\beta\share\bug\3.txt does NOT exist!
!!! File \\beta\share\bug\4.txt does NOT exist!
_

新しいファイルが作成されている共有ディレクトリを列挙することによってバグが発生することを発見しました。 Pythonos.listdir('//beta/share/bug')を呼び出してバグを再現します。 _C#_の場合:Directory.GetDirectories(@"\\beta\share\bug")。シェルで共有ディレクトリに移動し、lsまたはdirを呼び出すこともできます。

_Windows Server 2008 R2_でバグが見つかりました

Windowsエクスプローラーでalpha PCのディレクトリコンテンツをリアルタイムで監視できないことに注意してください。このディレクトリをエクスプローラーで開くとバグが発生しないためです。バグを再現する前に、このようなウィンドウをすべて閉じてください。各スクリプトの再起動後、既に作成されたすべてのファイルを共有から手動で削除する必要があります(スクリプトはかなり愚かで常に0.txtから始まるため)。

現在、この問題には2つの回避策があります。

  1. クライアントがこの状況を確認すると、問題のあるディレクトリに一時ファイルが作成されます-このファイルが魔法のように表示された後。
  2. 無効にするSMB 2.0: http://www.petri.co.il/how-to-disable-smb-2-on-windows-Vista-or-server-2008 .htm

誰かがこれまでに同様の問題を発見したことがあり、それが発生する理由とそれを「正しく修正する」方法を説明できますか?

ありがとう

24
Roman

同様の問題が発生し、最終的にこの問題の原因を発見しました。特定の問題は、SMB2ディレクトリキャッシュです。これは、 SMB2クライアントリダイレクターキャッシュコンポーネントの1つです

これは、クライアントによって実行された最近のディレクトリ列挙のキャッシュです。クライアントアプリケーションによって行われた後続の列挙要求、およびディレクトリ内のファイルのメタデータクエリは、キャッシュから実行できます。また、クライアントはディレクトリキャッシュを使用して、ディレクトリ内のファイルの有無を判別し、その情報を使用して、サーバー上に存在しないことがわかっているファイルをクライアントが繰り返し開こうとしないようにします。このキャッシュは、サーバー上のファイルセットにアクセスする複数のコンピューターで実行されている分散アプリケーションに影響を与える可能性があります。アプリケーションは、帯域外メカニズムを使用して、サーバー上のファイルの変更/追加/削除について互いに通知します。

この素晴らしい小さなキャッシュのデフォルト値は10秒です。これにより、見ている動作が生成されます。コードがシステムにそのディレクトリ/ファイルについて尋ねると、キャッシュされた結果(10秒前)を取得しているため、ファイルが存在しないことがわかります。 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanmanworkstation\Parameters\DirectoryCacheLifetime(DWORD)を0の値に設定すると、キャッシュが無効になり、ファイルが存在しないという問題が解決されます。意外なことに、この変更ではクライアントマシンの再起動は必要ありません。これにより、SMB2を有効にしておくこともできます。これは、SMB1を強制するよりも、多くの理由で優れているはずです。

さらに、問題の共有がWindowsエクスプローラーで開かれている場合は、キャッシュを使用しないでください。開いていると、システムはキャッシュをバイパスしてライブビューを継続するように指示します。ただし、コードを介して共有内の何かを変更することはできません。

この問題全体はWindows 2008 R2/7以降で修正されたと思いますが、絶対に確認することはできません。 これは、最新バージョンのWindowsではまだ問題です。詳細については、以下のコメントを参照してください。

41
Justin Michael

1か月が経過しましたが、回答がありません...

したがって、「Disable SMB 2.0 "ソリューション。少なくとも機能します。

http://www.petri.co.il/how-to-disable-smb-2-on-windows-Vista-or-server-2008.htm

3
Roman

SMBを無効にしたり、レジストリキーを介してキャッシュしたりする代わりに、魔法のサフィックス$NOCSC$を使用できます。これにより、すべてのWindows設定をそのままにして、同時に時間ファイルはキャッシュされません。

これは質問固有の例です:\\beta$NOCSC$\share\bug\1.txt

詳細が必要な場合は、このリンクを確認してください。

http://blog.wisefaq.com/2016/01/26/nocscno-client-side-caching/

3
zmechanic
3
user281806

これを回避する最も簡単な方法(OPで推奨)は、ファイルが表示されるはずのフォルダーに一時ファイルまたはサブフォルダーを作成し、すぐに削除することです。これにより、変更が可視化されます。

フォルダーにFileSystemWatcherを含めると、何も実行しない場合でも役立つことに気付きました。

2