如何在不遍历整个树的情况下判断目录树中的文件是否被更改?

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 快照才能有效地使用它。