我有许多 Redhat YUM 存储库的镜像,它们每天都会更新。用于完成此操作的命令是:
reposync --repoid=${i} --download_path=${destdir} --gpgcheck -l --download-metadata --downloadcomps --newest --delete
createrepo -s sha256 --checkts --update --workers=4 -g $destdir/$fn/comps.xml
变量(i、destdir 和 fn)在发出命令的脚本中设置。这一切都非常有效,团队使用镜子取得了良好的效果。
问题是,大约一年后,其中一个存储库积累了令人印象深刻的 updateinfo xml 文件堆栈,其名称模式为 <hash>-updateinfo.xml.gz:顶部目录中有 456MB,主目录中有 28.45GB。 repodata 子目录。该存储库仅包含 4GB 的包文件。
在此存储库上执行 yum makecache 的客户端最终会得到一个 4GB 的repmod.xml 文件。
我的问题是
- 为什么这些文件会累积,即使我指定了 --delete..?
- 我可以在不破坏存储库的情况下删除它们吗?
- 我使用的参数是最优的吗?我们想要镜像完整的存储库,但仅镜像每个包的最新版本。
编辑 2018 年 4 月 6 日
经过更深入的挖掘,我发现了更多提示,表明这些文件实际上并不是必需的。
存储库顶部目录中的 <hash>updateinfo.xml.gz 文件大小都大致相同,约为 3.8M。由于顶级目录中的所有文件被串联,repodata 目录(由 createrepo 创建/更新)中的文件大小不断增长。
例如:在这个 repodata 目录中,我有 129 个 gzip 压缩文件。第一个文件的平均大小与顶级目录中的文件相同,最后一个文件很大,有 129 个更新标签,而第一个文件只有 1 个。
# l -tr
total 29G
-rw-r--r-- 1 root root 3.5M Sep 28 2016 6f9c8bca09bb360b0ac2c18231168d45aa6ef51254fee7b791c6d09693677f4c-updateinfo.xml.gz
...
-rw-r--r-- 1 root root 465M May 17 03:21 1696bec0516791660751bb4a319b287f2a3a5ecfee086aefb73285f07cad3ac5-updateinfo.xml.gz
drwxr-xr-x 3 root root 20K May 22 12:37 ../
# gzip -dc 1696bec0516791660751bb4a319b287f2a3a5ecfee086aefb73285f07cad3ac5-updateinfo.xml.gz >updateinfo-big.xml
# gzip -dc 6f9c8bca09bb360b0ac2c18231168d45aa6ef51254fee7b791c6d09693677f4c-updateinfo.xml.gz >updateinfo.xml
# grep '<updates>' updateinfo.xml |wc -l
1
# grep '<updates>' updateinfo-big.xml |wc -l
129
# ls -1 *updateinfo.xml.gz|wc -l
129
# l updateinfo*
-rw-r--r-- 1 root root 2.4G Jun 4 17:09 updateinfo-big.xml
-rw-r--r-- 1 root root 18M Jun 4 17:10 updateinfo.xml
我猜想 reposync 应该在 createrepo 运行之前删除顶部目录中任何现有的 updateinfo.xml.gz 文件。客户端在执行 makecache 时从 repodata 目录获取最新的 gzip 压缩文件,并将其解压缩。
在发布上述问题后,我已将堆栈移动到备份目录,并且没有看到对客户端产生不利影响。
答案1
回答我自己的问题,为其他人记录这一点。
我们现在几乎可以肯定旧的 updateinfo.xml 文件对于需要来说是多余的。显然,它们的累积只是因为文件名前面的哈希值。基于此,我做了一些更改,现在存储库的大小基本上保持不变。
在其原始形式中,在问题中引用的 reposync 和 createrepo 命令之后,脚本运行gunzip,然后运行modifyrepo 命令,该命令在 ../repodata 目录中创建一个新的 updateinfo.xml.gz 文件:
if [ -n "$(/bin/ls -t $destdir/$fn/*updateinfo.xml.gz 2>/dev/null)" ]; then
gunzip -c $(/bin/ls -t $destdir/$fn/*updateinfo.xml.gz) > $destdir/$fn/updateinfo.xml 2>> $LOGFILE
modifyrepo $destdir/$fn/updateinfo.xml $destdir/$fn/repodata >> $LOGFILE 2>&1
fi
我将此部分更改为:
if [ -n "$(/bin/ls -t $destdir/$fn/*updateinfo.xml.gz 2>/dev/null)" ]; then
gunzip -c $(/bin/ls -tr $destdir/$fn/*updateinfo.xml.gz|tail -1) > $destdir/$fn/updateinfo.xml 2>> $LOGFILE
modifyrepo $destdir/$fn/updateinfo.xml $destdir/$fn/repodata >> $LOGFILE 2>&1
# clean up old update info - keeping only the 2 most recent files.
for i in $destdir/$fn $destdir/$fn/repodata; do
for j in `/bin/ls -t ${i}/*updateinfo.xml.gz|tail -n +3`; do
echo "removing security file "$(ls -l ${j}) >> $LOGFILE
/bin/rm -f ${j} >> $LOGFILE 2>&1
done
done
fi
由于时间戳和 tail 命令的反向排序,gunzip 命令仅解压最新的 updateinfo.xml。因此,repodata 目录中的新文件将仅包含一个版本。第二个更改是删除所有旧的 updateinfo.xml 文件,栏 2(以防万一)。
我们已经使用这个版本几个月了,没有发现任何不需要的副作用。