小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
前面关于rpm的介绍,基本都是使用层面的内容和作用。但是对于rpm包管理器本身能够完成的功能或提供的能力,基本没有介绍。因此想着查找一些这些方面的资料介绍。
软件包的演变史
在早期,软件包就是一些可以运行的程序组成的集合,通常还包含一些配置文件、额外的动态链接库。
例如,将针对某个平台编译好的二进制文件、程序所依赖的动态库文件(如 .so 和 .dll 为扩展名的文件)以及配置文件复制到一个目录中,这个目录就可以称为一个软件包。
但是,我们需要保证使用的软件包能够方便且快速地复制到另外的机器上运行,于是就开始选用压缩文件的方式来封装软件包。比如使用 tar 或者 gzip 压缩得到 .tar.gz、 .rar 或者 .zip 格式的文件,这就相当于获得了一个较为高级的软件包。
但是,这样的软件包有着明显的缺点,比如软件的重复冗余(包的大小也会偏大)、无法进行很好和统一地管理等问题。
于是,慢慢的基于软件包的管理器开始出现,像 .rpm、 .bin 或者 .deb 格式的软件包,它们既是软件包的一种格式,又是对软件包进行管理的一种包管理器。这种格式下的软件包,比单纯的压缩格式有了很大的发展,除了最基本的文件压缩功能,还能进行依赖管理维护、脚本嵌入等功能。
RPM包管理器的功能
RPM 的功能如下:
- 存储和数据压缩
- 文件安装
- 配置文件生成
- 系统服务注册
- 软件依赖检查和依赖输出
存储数据压缩
RPM具有软件包的基本功能 —— 数据压缩存储。
RPM 安装列表中的文件在按照某个指定的算法(如 gzip)压缩后,作为最终 RPM 文件的一个数据块,与其他控制信息存储进同一个文件中。最终所有的数据都存储在同一个 RPM 文件中。
文件安装
文件安装是软件包的一个基本功能,它将压缩的文件解压至目标操作系统上。安装过程中,还可能动态生成一些文件,并安装到系统中。

配置文件生成
配置文件既可能是预先写好的静态文件,也可能是根据安装环境动态生成的文件。
系统服务注册
使用 rpm 安装一些软件包,比如 apache,mysql-server 等,在安装完成后,目录 /etc/init.d/ 下会生成一个服务启动脚本文件,而且此服务还可能被加入到系统的自动启动服务中。
软件依赖检查
大多数程序都会依赖其他组件,比如数据库操作程序可能需要 libmysql 的支持。
为了保证每个软件在安装后都能正常运行,在安装过程中,软件安装程序需要对该软件包所依赖的所有元素进行检查。并解决这些依赖问题
其他功能
RPM 还有一个重要功能就是对嵌入脚本的支持:它支持在安装软件或者卸载软件的过程中,执行用户预定义的指令。
常用的脚本执行点如下:
- pre install
- post install
- pre uninstall
- post uninstall
四个脚本执行的时机点:pre/post install 表示在安装之前或之后;pre/post uninstall 表示在卸载之前或者之后。
RPM 管理器的数据库
查看
每次安装 rpm 包时,rpm 系统会将一些元信息存储在它的数据库中,使用 rpm -q
命令查询已安装软件、查询软件包的相关信息时,软件版本升级时版本之间的比较等,都将会查询这些数据库,数据库文件位于 /var/lib/rpm/ 目录中。
软件的数字签名信息也会记录在此数据库
如果 RPM 的数据库损坏,可能会导致 RPM 数据丢失,以及相应功能无法使用。
# file /var/lib/rpm/*
/var/lib/rpm/Basenames: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Conflictname: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/__db.001: Applesoft BASIC program data
/var/lib/rpm/__db.002: 386 pure executable not stripped
/var/lib/rpm/__db.003: 386 pure executable not stripped
/var/lib/rpm/Dirnames: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Group: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Installtid: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Name: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Obsoletename: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Packages: Berkeley DB (Hash, version 9, native byte-order)
/var/lib/rpm/Providename: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Requirename: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Sha1header: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Sigmd5: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Triggername: Berkeley DB (Btree, version 9, native byte-order)
复制代码
重建或重新初始化数据库
如果 RPM 的数据库损坏,首先可以尝试重建它,当无法重建时,则可能需要重新初始化数据库。
如果存在过多的或频繁的软件安装卸载,为了避免数据混乱或无效数据,保持数据库的纯净,也可以考虑重建数据库。
- 重建数据库
rpm --rebuilddb
复制代码
该命令会从已安装的软件包提取信息重建数据库,它从 /var/lib/rpm/Packages 这个文件中提取信息,其他所有的数据库文件都可以由这个文件重建。如果 RPM 的数据库是完好的,这个命令不会重建,而是对数据库中未使用的条目进行空间回收。
- 重新初始化一个新的 RPM 数据库
rpm --initdb
复制代码
如果rpm数据库损坏并无法重建,就只能使用 --initdb 参数命令重建数据库,它会创建一个新的空的 RPM 数据库。由于新建的数据库是空的,不到万不得已不要使用这个命令。