java git gc似乎覆盖了一个packfile,留下了一个打开的文件描述符,其中包含对“oldxxx.pack”的引用
在调试生产问题期间,我正在处理一个应用程序(Gerrit),该应用程序在缓存结构中保存对RandomAccessFile的引用
这些文件引用的是git存储库包文件
在存储库上的带外git gc
(不在应用程序内)未发生更改的过程中,似乎:
- 重写相同的包文件(相同的uuid)李>
- 文件描述符以(old xxx.pack)的形式出现在lsof的输出列表中,但立即被标记(删除)李>
我已经为这个重命名搜索了很多代码库,但都没有结果
我的问题是,如果git gc对具有打开的文件描述符的文件进行重命名/覆盖,这会是一个文件系统的怪癖吗
入境限制:
java 25700 user 246r REG 8,3 5090 1855936 ~/gerrit/git/RepoF.git/objects/pack/old-f4b8054434be1a227bdf8b12729efc1719f39708.pack (deleted)
git gc期间的inotify事件:
~/gerrit/git/RepoF.git/objects/pack/ OPEN,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ OPEN pack-f4b8054434be1a227bdf8b12729efc1719f39708.idx
~/gerrit/git/RepoF.git/objects/pack/ OPEN pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ ACCESS pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE pack-f4b8054434be1a227bdf8b12729efc1719f39708.idx
~/gerrit/git/RepoF.git/objects/pack/ OPEN,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ OPEN,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ OPEN,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ OPEN pack-f4b8054434be1a227bdf8b12729efc1719f39708.idx
~/gerrit/git/RepoF.git/objects/pack/ OPEN pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ ACCESS pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ CREATE tmp_pack_rG4dBh
~/gerrit/git/RepoF.git/objects/pack/ OPEN tmp_pack_rG4dBh
~/gerrit/git/RepoF.git/objects/pack/ MODIFY tmp_pack_rG4dBh
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_WRITE,CLOSE tmp_pack_rG4dBh
~/gerrit/git/RepoF.git/objects/pack/ CREATE tmp_idx_NfF4Jh
~/gerrit/git/RepoF.git/objects/pack/ OPEN tmp_idx_NfF4Jh
~/gerrit/git/RepoF.git/objects/pack/ MODIFY tmp_idx_NfF4Jh
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_WRITE,CLOSE tmp_idx_NfF4Jh
~/gerrit/git/RepoF.git/objects/pack/ MOVED_FROM tmp_pack_rG4dBh
~/gerrit/git/RepoF.git/objects/pack/ MOVED_TO .tmp-27710-pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ MOVED_FROM tmp_idx_NfF4Jh
~/gerrit/git/RepoF.git/objects/pack/ MOVED_TO .tmp-27710-pack-f4b8054434be1a227bdf8b12729efc1719f39708.idx
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE pack-f4b8054434be1a227bdf8b12729efc1719f39708.idx
~/gerrit/git/RepoF.git/objects/pack/ MOVED_FROM pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
---> ~/gerrit/git/RepoF.git/objects/pack/ MOVED_TO old-f4b8054434be1a227bdf8b12729efc1719f39708.pack <----
~/gerrit/git/RepoF.git/objects/pack/ MOVED_FROM pack-f4b8054434be1a227bdf8b12729efc1719f39708.idx
~/gerrit/git/RepoF.git/objects/pack/ MOVED_TO old-f4b8054434be1a227bdf8b12729efc1719f39708.idx
~/gerrit/git/RepoF.git/objects/pack/ ATTRIB .tmp-27710-pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ MOVED_FROM .tmp-27710-pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ MOVED_TO pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ ATTRIB .tmp-27710-pack-f4b8054434be1a227bdf8b12729efc1719f39708.idx
~/gerrit/git/RepoF.git/objects/pack/ MOVED_FROM .tmp-27710-pack-f4b8054434be1a227bdf8b12729efc1719f39708.idx
~/gerrit/git/RepoF.git/objects/pack/ MOVED_TO pack-f4b8054434be1a227bdf8b12729efc1719f39708.idx
---> ~/gerrit/git/RepoF.git/objects/pack/ DELETE old-f4b8054434be1a227bdf8b12729efc1719f39708.pack <----
~/gerrit/git/RepoF.git/objects/pack/ DELETE old-f4b8054434be1a227bdf8b12729efc1719f39708.idx
~/gerrit/git/RepoF.git/objects/pack/ OPEN,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ OPEN pack-f4b8054434be1a227bdf8b12729efc1719f39708.idx
~/gerrit/git/RepoF.git/objects/pack/ OPEN pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ ACCESS pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ OPEN,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE pack-f4b8054434be1a227bdf8b12729efc1719f39708.idx
~/gerrit/git/RepoF.git/objects/pack/ OPEN,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ OPEN pack-f4b8054434be1a227bdf8b12729efc1719f39708.idx
~/gerrit/git/RepoF.git/objects/pack/ OPEN pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ ACCESS pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ OPEN,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE pack-f4b8054434be1a227bdf8b12729efc1719f39708.pack
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE pack-f4b8054434be1a227bdf8b12729efc1719f39708.idx
~/gerrit/git/RepoF.git/objects/pack/ OPEN,ISDIR
~/gerrit/git/RepoF.git/objects/pack/ CLOSE_NOWRITE,CLOSE,ISDIR
# 1 楼答案
如果在存储库中执行标准
git gc
而不做任何更改,则这是意料之中的。Git根据其内容的散列来命名其打包文件。因为Git不会为现有包重新计算增量,当您git gc
并且只有一个包而没有松散对象时,它很可能会将所有数据打包到一个与旧包相同的包中发生这种情况时,Git仍然会打开旧包的文件描述符,因为它不会立即关闭包。这是因为经常需要再次访问它们,所以它会尝试让它们打开一段时间。仍处于打开状态的旧包将重命名为旧名称,新包将重命名到位;然后删除旧包。在Unix系统上,完全可以删除打开了文件描述符的文件;当最后一个进程关闭其文件描述符时,存储被释放
因此,对于您描述的场景来说,这一切似乎完全正常。通常
git gc
不是no op,因为会向包中添加或删除其他对象,或者将多个包合并为一个包。但是,如果您在运行一个git gc
之后立即运行一个git gc
,而没有中间更改,那么这是意料之中的