On Thu, Jul 15, 2021 at 12:46:47AM +0800, Sun Chao wrote: > > Stepping back, I'm not sure I understand why freshening a pack is so > > slow for you. freshen_file() just calls utime(2), and any sync back to > > the disk shouldn't need to update the pack itself, just a couple of > > fields in its inode. Maybe you could help explain further. > > > > [ ... ] > > The reason why we want to avoid freshen the mtime of ".pack" file is to > improve the reading speed of Git Servers. > > We have some large repositories in our Git Severs (some are bigger than 10GB), > and we created '.keep' files for large ".pack" files, we want the big files > unchanged to speed up git upload-pack, because in our mind the file system > cache will reduce the disk IO if a file does not changed. > > However we find the mtime of ".pack" files changes over time which makes the > file system always reload the big files, that takes a lot of IO time and result > in lower speed of git upload-pack and even further the disk IOPS is exhausted. That's surprising behavior to me. Are you saying that calling utime(2) causes the *page* cache to be invalidated and that most reads are cache-misses lowering overall IOPS? If so, then I am quite surprised ;). The only state that should be dirtied by calling utime(2) is the inode itself, so the blocks referred to by the inode corresponding to a pack should be left in-tact. If you're on Linux, you can try observing the behavior of evicting inodes, blocks, or both from the disk cache by changing "2" in the following: hyperfine 'git pack-objects --all --stdout --delta-base-offset >/dev/null' --prepare='sync; echo 2 | sudo tee /proc/sys/vm/drop_caches' where "1" drops the page cache, "2" drops the inodes, and "3" evicts both. I wonder if you could share the results of running the above varying the value of "1", "2", and "3", as well as swapping the `--prepare` for `--warmup=3` to warm your caches (and give us an idea of what your expected performance is probably like). Thanks, Taylor