Windows 文件共享:为什么有时新创建的文件在一段时间内不可见?

发布于 2024-10-19 13:13:11 字数 1993 浏览 6 评论 0原文

我们面临着非常奇怪的问题,让我们抓狂。有时,我们的文件共享电脑上新创建的文件会在一段时间内“不存在”。要重现问题,您应该至少有两台计算机,将它们称为 alphabeta。在 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 exit \\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!

我们发现该错误是由枚举正在创建新文件的共享目录引起的。在 Python 中,调用 os.listdir('//beta/share/bug') 来重现错误。在C#中:Directory.GetDirectories(@"\\beta\share\bug")。您甚至可以简单地通过 shell 导航到共享目录并调用 lsdir

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

有没有人发现过类似的问题,并可以解释为什么会发生以及如何发生“正确修复”它吗?

谢谢

We were faced with very strange issue that made us crazy. Sometimes newly created files on our File Share PC were "absent" for some period of time. To reproduce a problem you should have at least two computers, call them alpha and beta. Create file share on beta PC (\\beta\share\bug) and run this PowerShell script from alpha PC:

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
}

After starting this script you should be able to see these messages:

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

And now:
Open cmd.exe and run this command:

if exist \\beta\share\bug\foo.txt echo 1

After this during approx 10 seconds you'll see following messages:

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

We've discovered that bug is caused by enumerating shared directory where new files are being created. In Python call os.listdir('//beta/share/bug') to reproduce a bug. In C#: Directory.GetDirectories(@"\\beta\share\bug"). You can even simply navigate to share directory by shell and call ls or dir.

Bug were found on Windows Server 2008 R2

Note, that you cannot watch directory content on alpha PC in Windows Explorer in real time, because if you open this directory in Explorer bug would not occur! So ensure to close all such windows before attempts to reproduce a bug. After each script restart you should manually remove all already created files from share (because script is rather stupid and always starts from 0.txt).

We currently have 2 workarounds for this issue:

  1. If client sees this situation, it creates some temporary file in problematic directory - after this files magically appear.
  2. Disable SMB 2.0: http://www.petri.co.il/how-to-disable-smb-2-on-windows-vista-or-server-2008.htm

Does anybody have ever discovered similar problem and can explain why it occurs and how "correctly fix" it?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

灵芸 2024-10-26 13:13:11

我也遇到了类似的问题,最终我找到了这个问题的原因。具体问题是 SMB2 目录缓存,它是 SMB2 客户端重定向器缓存组件

这是客户端最近执行的目录枚举的缓存。客户端应用程序发出的后续枚举请求以及目录中文件的元数据查询都可以从缓存中得到满足。客户端还使用目录缓存来确定目录中是否存在文件,并使用该信息来防止客户端重复尝试打开已知服务器上不存在的文件。此缓存可能会影响在访问服务器上的一组文件的多台计算机上运行的分布式应用程序,其中应用程序使用带外机制相互发出有关服务器上文件的修改/添加/删除的信号。

这个奇妙的小缓存的默认值为 10 秒,这会产生您所看到的行为。当您的代码向系统询问该目录/文件时,它会获取缓存的结果,该结果是 10 秒前的结果,因此它表示该文件不存在。将 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanmanworkstation\Parameters\DirectoryCacheLifetime (DWORD) 设置为值 0 将禁用缓存并解决文件不存在问题。令人惊讶的是,此更改不需要需要重新启动客户端计算机!这还允许您保持 SMB2 启用,出于多种原因,这应该比强制 SMB1 更好。

此外,当在 Windows 资源管理器中打开相关共享时,不会使用缓存,因为打开它会告诉系统绕过缓存以保持实时视图的运行。但是,通过代码修改共享中的某些内容则不然。

我认为整个问题在 Windows 2008 R2/7 及更高版本中已得到解决,但我不能绝对确认。这仍然是现代版本 Windows 中的一个问题。详情请参阅下面的评论。

I was experiencing a similar problem and, eventually, I found the cause of this issue. The specific problem is the SMB2 Directory Cache, which is one of the SMB2 Client Redirector cache components:

This is a cache of recent directory enumerations performed by the client. Subsequent enumeration requests made by client applications as well as metadata queries for files in the directory can be satisfied from the cache. The client also uses the directory cache to determine the presence or absence of a file in the directory and uses that information to prevent clients from repeatedly attempting to open files which are known not to exist on the server. This cache is likely to affect distributed applications running on multiple computers accessing a set of files on a server – where the applications use an out of band mechanism to signal each other about modification/addition/deletion of files on the server.

The default value for this wonderful little cache is 10 seconds, which is producing the behavior you're seeing. When your code asks the system about that directory/file it's getting the cached result, which is 10 seconds old, so it says the file does not exist. Setting HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanmanworkstation\Parameters\DirectoryCacheLifetime (DWORD) to a value of 0 will disable the cache and resolve the file doesn't exist issue. Surprisingly this change does not require a restart of the client machine! This will also allow you to keep SMB2 enabled, which should be better for a number of reasons vs. forcing SMB1.

Furthermore, the cache is not used when the share in question is opened in Windows explorer, as having it open tells the system to bypass the cache to keep a live view going. Modifying something in the share via code, however, does not.

I think this whole issue is fixed in Windows 2008 R2/7 and higher, but I cannot absolutely confirm it. This is still an issue in modern versions of Windows. See the comments below for details.

維他命╮ 2024-10-26 13:13:11

一个月过去了,没有任何答复...

因此,我们继续使用“禁用 SMB 2.0”解决方案。至少它有效。

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

A month passed and no answer...

So, we stayed with "Disable SMB 2.0" solution. At least it works.

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

我不会写诗 2024-10-26 13:13:11

您可以使用神奇的后缀 $NOCSC$,而不是像其他人建议的那样通过注册表项禁用 SMB 或缓存。这将允许您保持所有 Windows 设置不变,但同时文件将不会被缓存。

这是一个问题的具体示例:
\\beta$NOCSC$\share\bug\1.txt

如果您想了解更多详细信息,请查看此链接:

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

You can use magical suffix $NOCSC$, instead of disabling SMB or caching via registry keys, as some others suggested. This will allow you to leave all Windows settings intact, but at the same time files will not get cached.

Here is a question specific example:
\\beta$NOCSC$\share\bug\1.txt

Check this link if you want more details:

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

贪了杯 2024-10-26 13:13:11

解决此问题的最简单方法(按照OP的建议)是在您希望文件出现的文件夹中创建一个临时文件或子文件夹,并立即将其删除。这会触发变化变得可见。

我们注意到,在文件夹中添加 FileSystemWatcher 也有帮助,即使它什么也不做。

The easiest way to work around this (as suggested by the OP) is to create a temporary file or subfolder in the folder where you expect the files to appear and remove it right away. This triggers the change to become visible.

We noticed that having a FileSystemWatcher in the folder also helps, even when it does nothing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文