如何在不遍历整个树的情况下判断目录树中的文件是否被更改?
How to determine whether files have been changed in a directory tree without traversing the entire tree?
想象一个目录树(在 Linux 上):
user@computer:~/demo> find .
.
./test1
./test1/test1_a
./test1/test1_a/somefile_1a
./test1/test1_b
./test1/test1_b/somefile_1b
./test0
./test0/test0_a
./test0/test0_a/somefile_0a
./test0/test0_b
./test0/test0_b/somefile_0b
场景:我确定关于该树中每个目录和文件的所有可用元信息(mtime、ctime、inode、大小、文件内容的校验和...),包括最高级别的目录,demo
.我存储这些信息。然后,一些 file/s 或 directory/ies is/are 改变了(字面上改变或新建或删除)。使用先前确定和存储的信息,我现在想弄清楚发生了什么变化。
我目前的解决方案:我遍历整棵树,然后寻找变化的元信息,然后处理它。超过一定大小,遍历树并查看每个目录和文件变得非常耗时——即使您只查看纯元信息(即 ctime、mtime 等,而不是文件内容校验和)。人们只能在一定程度上优化这种遍历(例如,在遍历过程中实际上只读取一次文件和文件夹的元信息,而不是多次等)——最终 I/O 速度成为瓶颈。
问题:我有什么选择(在 Unix / Linux 文件系统上)来查找我的树中的更改而不遍历所有它? 即是否有为 demo
存储的任何信息以某种方式告诉我/表明其下方的某些内容(例如 somefile_1b
)已被更改? 是否有任何特定的文件系统(EXT*、XFS、ZFS 等)提供此类功能?
注意:I am aware of the option of running a background process for monitoring changes to the filesystem.这将消除对我的树进行完整遍历的需要,尽管我对不需要后台监视进程的选项更感兴趣(如果存在这种选项的话) ).
ZFS 通过 zfs diff ...
Per the Oracle Solaris 11.2 documentation:
提供功能
Identifying ZFS Snapshot Differences (zfs diff)
You can determine ZFS snapshot differences by using the zfs diff
command.
For example, assume that the following two snapshots are created:
$ ls /tank/home/tim
fileA
$ zfs snapshot tank/home/tim@snap1
$ ls /tank/home/tim
fileA fileB
$ zfs snapshot tank/home/tim@snap2
For example, to identify the differences between two snapshots, use
syntax similar to the following:
$ zfs diff tank/home/tim@snap1 tank/home/tim@snap2
M /tank/home/tim/
+ /tank/home/tim/fileB
In the output, the M indicates that the directory has been modified.
The + indicates that fileB exists in the later snapshot.
The R in the following output indicates that a file in a snapshot has
been renamed.
$ mv /tank/cindy/fileB /tank/cindy/fileC
$ zfs snapshot tank/cindy@snap2
$ zfs diff tank/cindy@snap1 tank/cindy@snap2
M /tank/cindy/
R /tank/cindy/fileB -> /tank/cindy/fileC
这只会比较两个快照,因此您必须能够创建 ZFS 快照才能有效地使用它。
想象一个目录树(在 Linux 上):
user@computer:~/demo> find .
.
./test1
./test1/test1_a
./test1/test1_a/somefile_1a
./test1/test1_b
./test1/test1_b/somefile_1b
./test0
./test0/test0_a
./test0/test0_a/somefile_0a
./test0/test0_b
./test0/test0_b/somefile_0b
场景:我确定关于该树中每个目录和文件的所有可用元信息(mtime、ctime、inode、大小、文件内容的校验和...),包括最高级别的目录,demo
.我存储这些信息。然后,一些 file/s 或 directory/ies is/are 改变了(字面上改变或新建或删除)。使用先前确定和存储的信息,我现在想弄清楚发生了什么变化。
我目前的解决方案:我遍历整棵树,然后寻找变化的元信息,然后处理它。超过一定大小,遍历树并查看每个目录和文件变得非常耗时——即使您只查看纯元信息(即 ctime、mtime 等,而不是文件内容校验和)。人们只能在一定程度上优化这种遍历(例如,在遍历过程中实际上只读取一次文件和文件夹的元信息,而不是多次等)——最终 I/O 速度成为瓶颈。
问题:我有什么选择(在 Unix / Linux 文件系统上)来查找我的树中的更改而不遍历所有它? 即是否有为 demo
存储的任何信息以某种方式告诉我/表明其下方的某些内容(例如 somefile_1b
)已被更改? 是否有任何特定的文件系统(EXT*、XFS、ZFS 等)提供此类功能?
注意:I am aware of the option of running a background process for monitoring changes to the filesystem.这将消除对我的树进行完整遍历的需要,尽管我对不需要后台监视进程的选项更感兴趣(如果存在这种选项的话) ).
ZFS 通过 zfs diff ...
Per the Oracle Solaris 11.2 documentation:
Identifying ZFS Snapshot Differences (zfs diff)
You can determine ZFS snapshot differences by using the
zfs diff
command.For example, assume that the following two snapshots are created:
$ ls /tank/home/tim fileA $ zfs snapshot tank/home/tim@snap1 $ ls /tank/home/tim fileA fileB $ zfs snapshot tank/home/tim@snap2
For example, to identify the differences between two snapshots, use syntax similar to the following:
$ zfs diff tank/home/tim@snap1 tank/home/tim@snap2 M /tank/home/tim/ + /tank/home/tim/fileB
In the output, the M indicates that the directory has been modified. The + indicates that fileB exists in the later snapshot.
The R in the following output indicates that a file in a snapshot has been renamed.
$ mv /tank/cindy/fileB /tank/cindy/fileC $ zfs snapshot tank/cindy@snap2 $ zfs diff tank/cindy@snap1 tank/cindy@snap2 M /tank/cindy/ R /tank/cindy/fileB -> /tank/cindy/fileC
这只会比较两个快照,因此您必须能够创建 ZFS 快照才能有效地使用它。