
最近公司部署了基于微软DFS技术的文件服务器。其中最吸引人的技术恐怕就是DFSR(DFS Replication)了。但是经过一段时间的运营,用户在抱怨为什么其他省的文件,自己却看不到?经过一番查找,发现问题居然是,这些文件的属性是Temporary(临时性)的。而DFSR默认的设计,则不会阀值这些带有Temporary属性的文件,并且DFSR的这个特性目前为止还不能配置(2008R2)。
事实上,你根本无法轻易的看到一个文件的文件属性是否是Temporary的。甚至微软提供的一些命令行,例如Attrib.exe,FileSystemObject或者WMI中的CIM_Datafile都无法查看一个文件的Temporary属性,更悲情的是:DFSR本身对这些文件的处理(不同步)不会留下任何的Log,对DFSR来讲,这更不是一个Error或者是Bug了,因为本身就是这么设计的。
理论上,这些文件Temporary属性的文件是指只会临时性使用的文件,而不是用户想要真正存档的,DFSR不复制这些文件是基于提升整个复制效率来考虑的,同时,应用程序为了提升自我的处理效率,也必然会产生大量的临时属性文件。当应用程序要创建一个文件(CreateFile)时,可以使用FILE_ATTRIBUTE_TEMPORARY来创建一个temporary属性文件,但更好的方式是同时指定FILE_FLAG_DELETE_ON_CLOSE属性,这样当程序所有的进程都关闭的时候,temporary文件也可以被删除。
但事实上在Leo的实际生产环境中,用户正常的Office文件,Adobe PDF文件等许多的文件都莫名奇妙的有了Temporary属性,事实这些文件都一定是要被复制到DFS的其他服务器上;于是,Leo只能需求去掉Temporary属性的方法。
使用Fsutil命令查看Temporary属性。
Fsutil是包含在Windows系统中的一个命令工具,用法:
fsutil usn readdata c:\data\test.txt
Major Version : 0x2
Minor Version : 0x0
FileRef# : 0x0021000000002350
Parent FileRef# : 0x0003000000005f5e
Usn : 0x000000004d431000
Time Stamp : 0x0000000000000000 12:00:00 AM 1/1/1601
Reason : 0x0
Source Info : 0x0
Security Id : 0x5fb
File Attributes : 0x120
File Name Length : 0x10
File Name Offset : 0x3c
FileName : test.txt
File Attributes是一个位掩码,表示文件属性的设定值。在上面的例子中,0×120表明为一个临时文件,计算方式是:
0×100 × 0×20 (Archive) = 0×120.
以下列出的文件属性和值的对应表:
| READONLY |
0×1
|
|
HIDDEN
|
0×2
|
|
SYSTEM
|
0×4
|
|
DIRECTORY
|
0×10
|
|
ARCHIVE
|
0×20
|
|
DEVICE
|
0×40
|
|
NORMAL
|
0×80
|
|
TEMPORARY
|
0×100
|
|
SPARSE_FILE
|
0×200
|
|
REPARSE_POINT
|
0×400
|
|
COMPRESSED
|
0×800
|
|
OFFLINE
|
0×1000
|
|
NOT_CONTENT_INDEXED
|
0×2000
|
|
ENCRYPTED
|
0×4000
|
这些值结合起来,是文件属性的位码值。
在Debug Log是使用Findstr命令查找Temporary文件。
对于没有复制的文件,DFSR其实是有记录可查的,使用Findstr(包含在windows服务器中的命令工具)通过查找DFSR的Debug Logs中的名为FILE_ATTRIBUTE_TEMPORARY的字段,即可找到哪些文件没有被复制。
首先,因为Log文件被压缩为后缀名为.GZ的压缩包,所以你需要导出所有的DFSR的Debug Logs。默认的log存在于%windir%\debug目录下,找到名为Dfsr*.log和Dfsr*.log.gz解压即可。
假如你导出log到C:\logs下,你可以运行以下的命令查找Temporary文件。
Findstr FILE_ATTRIBUTE_TEMPORARY c:\logs\dfsr*.log
命令会输出包含FILE_ATTRIBUTE_TEMPORARY字段的命令行,如下:
C:\WINDOWS\debug\Dfsr00018.log:20080903 16:14:29.390 1808 USNC 1204 UsnConsumer::ProcessUsnRecord Skipping USN_RECORD with FILE_ATTRIBUTE_TEMPORARY flag:
或者你也可以用记事本等工具打开log文件,使用查找功能,查找FILE_ATTRIBUTE_TEMPORARY字段。
使用Powershell查找Temporary属性的文件。
另外一种更简便的方式是使用PowerShell www.microsoft.com/powershell:
例如我的想找到D:\Data文件夹下面的具有临时文件属性的文件,使用以下的命令:
Get-childitem D:\Data -recurse | ForEach-Object -process {if(($_.attributes -band 0x100) -eq 0x100) {write-output $_}}
使用Powershell移除文件的Temporary属性。
知道了病因,接下来就是对症下药。不过不幸的是,最简单的方式是使用powershell。所以没有Powershell的同学,先去安装一个吧www.microsoft.com/powershell
例如我的想移除D:\Data文件夹下面的所有文件的临时属性,使用以下的命令:
Get-childitem D:\Data -recurse | ForEach-Object -process {if (($_.attributes -band 0x100) -eq 0x100) {$_.attributes = ($_.attributes -band 0xFEFF)}}