为什么 rpm -qa base* 这么慢?

为什么 rpm -qa base* 这么慢?

我想知道: rpm使用(简单)数据库来存储数据包名称等内容。当使用rpm -qa查询该数据库时,速度非常慢。

例如,当磁盘“洗牌”时,此命令花费了近一分钟才能完成:

# rpm -qa rtl8812au-kmp\*
rtl8812au-kmp-preempt-5.9.3.2+git20210427.6ef5d8f_k5.3.18_57-lp153.1.1.x86_64
rtl8812au-kmp-default-5.9.3.2+git20210427.6ef5d8f_k5.3.18_57-lp153.1.1.x86_64

当然,第二次调用要快得多,因为所有数据都在磁盘缓存中,因此“仅”花费了 2.2 秒。然而,“快速”的拼写有所不同。

# grep MHz /proc/cpuinfo 
cpu MHz     : 3998.528
...
# LANG= time dd if=/var/lib/rpm/Packages of=/dev/null
748816+0 records in
748816+0 records out
383393792 bytes (383 MB, 366 MiB) copied, 0.606612 s, 632 MB/s
0.30user 0.29system 0:00.60elapsed 99%CPU (0avgtext+0avgdata 1876maxresident)k
0inputs+0outputs (0major+81minor)pagefaults 0swaps
# LANG= time rpm -qa rtl8812au-kmp\*
rtl8812au-kmp-preempt-5.9.3.2+git20210427.6ef5d8f_k5.3.18_57-lp153.1.1.x86_64
rtl8812au-kmp-default-5.9.3.2+git20210427.6ef5d8f_k5.3.18_57-lp153.1.1.x86_64
2.17user 0.06system 0:02.24elapsed 99%CPU (0avgtext+0avgdata 32472maxresident)k
0inputs+0outputs (0major+6302minor)pagefaults 0swaps

因此,完全读取完整的包(名称)数据库比搜索特定名称更快!

/var(根)文件系统放置ext3在 LV 上,其中 VG 的 PV 是由 RAID1 (imsm) 分区创建的 LUKS 加密卷:

# hdparm -t /dev/mapper/system-root
/dev/mapper/system-root:
 Timing buffered disk reads: 242 MB in  3.02 seconds =  80.19 MB/sec

# hdparm -t /dev/mapper/cr_md-uuid-fe1588c4:a2140388:5b4117ba:4e4339b9-part5
/dev/mapper/cr_md-uuid-fe1588c4:a2140388:5b4117ba:4e4339b9-part5:
 Timing buffered disk reads: 240 MB in  3.03 seconds =  79.33 MB/sec

# hdparm -t /dev/disk/by-id/md-uuid-fe1588c4:a2140388:5b4117ba:4e4339b9-part5
/dev/disk/by-id/md-uuid-fe1588c4:a2140388:5b4117ba:4e4339b9-part5:
 Timing buffered disk reads: 290 MB in  3.01 seconds =  96.32 MB/sec

# hdparm -t /dev/md126
/dev/md126:
 Timing buffered disk reads: 408 MB in  3.01 seconds = 135.63 MB/sec

# hdparm -t /dev/sda
/dev/sda:
 Timing buffered disk reads: 394 MB in  3.01 seconds = 130.92 MB/sec

# hdparm -t /dev/sdb
/dev/sdb:
 Timing buffered disk reads: 444 MB in  3.03 seconds = 146.61 MB/sec

时序示例

抱歉,这是一个较晚的补充,但我必须记住在启动后在 RPM 数据库文件进入缓存之前进行计时测试。

~> time rpm -qa libavd\*
libavdevice58_13-4.4-pm153.2.8.x86_64
libavdevice57-3.4.9-pm153.1.2.x86_64

real    1m15,788s
user    0m2,727s
sys 0m0,613s
~> time rpm -qa libavd\*
libavdevice58_13-4.4-pm153.2.8.x86_64
libavdevice57-3.4.9-pm153.1.2.x86_64

real    0m2,300s
user    0m2,220s
sys 0m0,080s

因此,对于 RAM 缓存中的所有文件,该命令仍然需要 2.2 秒的用户 CPU。

重建数据库的效果

(抱歉,区域设置是de_DE

# ll /var/lib/rpm/
insgesamt 447440
-rw-r--r-- 1 root root  20901888 28. Jan 20:35 Basenames
-rw-r--r-- 1 root root     28672 28. Jan 20:35 Conflictname
-rw-r--r-- 1 root root  12189696 28. Jan 20:35 Dirnames
-rw-r--r-- 1 root root      8192 27. Jan 21:40 Enhancename
-rw-r--r-- 1 root root      8192 22. Jan 22:51 Filetriggername
-rw-r--r-- 1 root root     77824 28. Jan 20:35 Group
-rw-r--r-- 1 root root    184320 28. Jan 20:35 Installtid
-rw-r--r-- 1 root root    319488 28. Jan 20:35 Name
-rw-r--r-- 1 root root     94208 28. Jan 20:35 Obsoletename
-rw-r--r-- 1 root root 409018368 28. Jan 20:35 Packages
-rw-r--r-- 1 root root  11694080 28. Jan 20:35 Providename
-rw-r--r-- 1 root root    114688 28. Jan 20:35 Recommendname
-rw-r--r-- 1 root root   1339392 28. Jan 20:35 Requirename
-rw-r--r-- 1 root root         0 26. Okt 2014  .rpm.lock
-rw-r--r-- 1 root root    634880 28. Jan 20:35 Sha1header
-rw-r--r-- 1 root root    360448 28. Jan 20:35 Sigmd5
-rw-r--r-- 1 root root     20480 27. Jan 21:40 Suggestname
-rw-r--r-- 1 root root    667648 28. Jan 20:34 Supplementname
-rw-r--r-- 1 root root      8192 20. Nov 2018  Transfiletriggername
-rw-r--r-- 1 root root      8192 31. Dez 02:06 Triggername
# rpm --rebuilddb 
# ll /var/lib/rpm/
insgesamt 373392
-rw-r--r-- 1 root root  16920576  3. Feb 21:26 Basenames
-rw-r--r-- 1 root root     24576  3. Feb 21:26 Conflictname
-rw-r--r-- 1 root root   7684096  3. Feb 21:26 Dirnames
-rw-r--r-- 1 root root      8192  3. Feb 21:26 Enhancename
-rw-r--r-- 1 root root      8192  3. Feb 21:26 Filetriggername
-rw-r--r-- 1 root root     77824  3. Feb 21:26 Group
-rw-r--r-- 1 root root    139264  3. Feb 21:26 Installtid
-rw-r--r-- 1 root root    311296  3. Feb 21:26 Name
-rw-r--r-- 1 root root     77824  3. Feb 21:26 Obsoletename
-rw-r--r-- 1 root root 343470080  3. Feb 21:26 Packages
-rw-r--r-- 1 root root  10416128  3. Feb 21:26 Providename
-rw-r--r-- 1 root root    114688  3. Feb 21:26 Recommendname
-rw-r--r-- 1 root root   1204224  3. Feb 21:26 Requirename
-rw-r--r-- 1 root root    503808  3. Feb 21:26 Sha1header
-rw-r--r-- 1 root root    311296  3. Feb 21:26 Sigmd5
-rw-r--r-- 1 root root     16384  3. Feb 21:26 Suggestname
-rw-r--r-- 1 root root    647168  3. Feb 21:26 Supplementname
-rw-r--r-- 1 root root      8192  3. Feb 21:26 Transfiletriggername
-rw-r--r-- 1 root root      8192  3. Feb 21:26 Triggername
# 

升级到 OpenSUSE Leap 15.5 后问题仍然存在(内核 5.14.21-150500.55.12-default,rpm-4.14.3-150300.55.1.x86_64):

> # directly after boot and login, so most likely no data cached
> time rpm -qa >/tmp/rpmlist-poweroff

real    0m58,971s
user    0m3,016s
sys 0m0,472s
> time rpm -qa 'base*'

real    0m2,644s
user    0m2,603s
sys 0m0,040s
> # when the data is in cache, it's mostly CPU-bound

所以问题似乎是过多(无用?)I/O。

答案1

我最近通过使用 rpm 的 verbose 标志发现,rpm -qa -vvv我正在使用的操作系统 (RHEL 8) 上的 rpm 在查询所有包时会进行签名和摘要检查。添加--nodigest--nosignature标志显着缩短了我的时间。

rpm -qa --nodigest --nosignature base*

我的系统的示例计时:

$ free && sync && echo 3 > /proc/sys/vm/drop_caches && free
$ time rpm -qa > /dev/null

real: 0m2.944s
user: 0m1.689s
sys:  0m0.163s
$ time rpm -qa > /dev/null

real: 0m1.740s
user: 0m1.644s
sys:  0m0.079s
$ free && sync && echo 3 > /proc/sys/vm/drop_caches && free
$ time rpm -qa --nodigest --nosignature > /dev/null

real: 0m1.319s
user: 0m0.259s
sys:  0m0.147s
$ time rpm -qa --nodigest --nosignature > /dev/null

real: 0m0.366s
user: 0m0.235s
sys:  0m0.099s

现在我只需要发现是否有一种方法可以安全地配置系统(也许编辑或覆盖宏)以将其设置为-qa.

相关内容