1. 事件背景
在日常维护中,因发现 /var/lib/dnf 目录下 sqlite-wal 文件过大,为清理磁盘执行了删除操作。随后通过备份/系统手段恢复了数据。本文档记录了恢复后的数据压缩过程及长期维护建议。
2. 优化前后的详细数据对比 (ls -lh)
2.1 初始恢复状态 (18M)
此时数据库存在碎片,且包含运行时的临时映射文件(__db.*)。
[root@localhost ~]# ls -lh /var/lib/rpm/
total 18M
-rw-r--r--. 1 root root 2.2M 2月 13 16:33 Basenames
-rw-r--r--. 1 root root 8.0K 1月 29 16:32 Conflictname
-rw-r--r--. 1 root root 280K 2月 13 16:37 __db.001
-rw-r--r--. 1 root root 88K 2月 13 16:37 __db.002
-rw-r--r--. 1 root root 1.3M 2月 13 16:37 __db.003
-rw-r--r--. 1 root root 560K 2月 13 16:33 Dirnames
-rw-r--r--. 1 root root 13M 2月 13 16:33 Packages
...(其他小文件省略)...
[root@localhost ~]# du -s /var/lib/rpm/
17928 /var/lib/rpm/
2.2 重建优化后状态 (14M)
执行 rpm --rebuilddb 后,系统重新整理了 Berkeley DB 结构,删除了冗余碎片,并自动清理了 __db.* 文件。
[root@localhost ~]# rpm --rebuilddb
[root@localhost ~]# ls -lh /var/lib/rpm/
total 14M
-rw-r--r--. 1 root root 2.1M 2月 13 16:39 Basenames
-rw-r--r--. 1 root root 8.0K 2月 13 16:39 Conflictname
-rw-r--r--. 1 root root 484K 2月 13 16:39 Dirnames
-rw-r--r--. 1 root root 11M 2月 13 16:39 Packages
...(其他索引文件已同步重建)...
[root@localhost ~]# du -s /var/lib/rpm/
14096 /var/lib/rpm/
数据结论:通过重建索引,核心文件 Packages 从 13M 减小至 11M,目录总体积缩减了约 21.4%。
3. 核心原理解析
3.1 为什么会产生体积膨胀?
BDB 碎片化:RPM 4.15 使用的 Berkeley DB 格式在频繁增删包后,文件内部会留下空洞。
DNF WAL 机制:
/var/lib/dnf/history.sqlite-wal是 SQLite 的预写日志。在高并发写或事务未提交时,该文件会迅速增长(如你之前看到的 4.0M)。
4. 正确的“脱水”清理流程
若未来磁盘空间紧张,请按顺序执行以下操作,严禁使用 rm -rf 直接删除目录:
第一步:安全清理 DNF 缓存
# 清理下载的 rpm 包及旧的元数据
dnf clean all
第二步:压缩 RPM 数据库(针对 /var/lib/rpm)
# 重建索引并回收 BDB 碎片
rpm --rebuilddb
第三步:清理 DNF 历史记录(针对 /var/lib/dnf)
如果不依赖 dnf history 命令查看过去的操作记录,可执行:
# 停止 DNF 进程后删除
rm -f /var/lib/dnf/history.sqlite*
5. 预防性配置建议
为了防止数据库无限制增长,建议在 /etc/dnf/dnf.conf 中加入以下行:
[main]
# 限制事务历史记录保留条数(默认通常无限制或很大)
history_list_max=10
文档说明:本笔记适用于使用 RPM 4.15 (BDB 格式) 的系统(如 CentOS 8, RHEL 8 早期版本)。对于 RPM 4.16+ (SQLite 格式) 的系统,优化方式略有不同(主要使用 VACUUM)。