RPM Database 实战详解

本文围绕RPMDatabase,介绍RPM包的查询、依赖关系、验证及数据库的备份与恢复等内容,帮助解决软件包相关问题。

概述:

  RPM 不仅在安装、升级、卸载方面工作出色,而且在查询和验证方面也表现非凡。你很久前安装了一个数据库软件,但现在忘记了它的版本号,也不知道它的说明文档的位置,可以通过 RPM 查询命令得到这个信息;你有一个系统安全方面的包要升级,但是不清楚哪些相关包会受到影响,可以通过 RPM 依赖查询来确定;你系统中安装了一个网络软件,想了解哪些文件发生了变化,可以通过 RPM 验证命令获悉。这些操作都得益于 RPM Database,RPM Database 记录了已安装 RPM 包的所有信息,使得我们可以方便地查询和验证 RPM。本文结合实际例子,带大家走入 RPM Database 的世界。

简介:

  RPM 是 RPM Package Manager 的简写,是发源于 Red-hat 系统的软件管理工具,所以最初的名字叫做 Red-hat Packager Manager。目前,RPM 已发展成为业界认可的 Linux 系统软件管理工具,适用于各种基于 Linux 内核的系统,如 SUSE、Fedora、Power 等。RPM 制作灵活且方便使用,能够有效地管理软件包的安装、卸载和升级。
  RPM 自身维护了一个数据库(RPM Database),用于记录所有通过 RPM 安装的软件包及其文件信息。RPM Database 提供多种形式的查询功能,同时也提供软件包和相关文件的验证功能。下面我们结合一些实际的例子来重点介绍 RPM Database 的查询功能、验证功能以及 RPM Database 的备份与恢复。

RPM 包组件查询:

  RPM Database 记录了通过 RPM 安装的软件包的所有信息,我们可以使用 rpm 命令对其进行查询。 可查询的内容包括:软件包的名称、版本、描述信息、配置文件、文档文件、安装卸载前后运行的脚本和软件包的修改历史等。 下面,我们通过常见的组件查询例子来详细说明。


1. 列出全部已安装的 RPM 包

命令格式:rpm -qa

清单 1. 列出系统中已安装的全部 RPM 包
[root@nimbus-bvt-osee-kilo-rh7 ~]# rpm -qa 
 libchamplain-gtk-0.12.4-4.el7.x86_64 
 python-heatclient-0.4.0-1.ibm.el7.noarch 
 perl-Filter-1.49-3.el7.x86_64 
 pinentry-0.8.1-14.el7.x86_64 
 iso-codes-3.46-2.el7.noarch 
 zip-3.0-10.el7.x86_64 
 p11-kit-0.20.7-3.el7.x86_64 
 dbus-1.6.12-11.el7.x86_64 
 python-itsdangerous-0.22-2.ibm.el7.noarch 
 libXvMC-1.0.8-2.1.el7.x86_64 
 python-requests-2.6.0-1.el7_1.noarch 
 compat-openldap-2.3.43-5.el7.x86_64 
 # The following lines are omitted

在实际的应用中,该命令常常结合通配符或管道命令,实现一些特定的查找功能。比如:
清单 2. 结合通配符,查询以 mysql 开头的 rpm 包
[root@server01 ~]# rpm -qa "mysql*"
 mysql-server-5.1.73-5.el6_6.x86_64 
 mysql-5.1.73-5.el6_6.x86_64 
 mysql-devel-5.1.73-5.el6_6.x86_64 
 mysql-libs-5.1.73-5.el6_6.x86_64

清单 3. 结合管道命令,查询系统中近期安装的 rpm 包
[root@server01 ~]# rpm -qa --last | head 
 chefdk-0.6.2-1.el6.x86_64                     Wed 09 Sep 2015 10:51:29 PM EDT 
 docker-engine-1.7.1-1.el6.x86_64              Fri 24 Jul 2015 09:39:25 PM EDT 
 mysql-devel-5.1.73-5.el6_6.x86_64             Wed 08 Jul 2015 02:51:59 AM EDT 
 mysql-server-5.1.73-5.el6_6.x86_64            Wed 08 Jul 2015 02:51:58 AM EDT 
 perl-DBD-MySQL-4.013-3.el6.x86_64             Wed 08 Jul 2015 02:51:56 AM EDT 
 mysql-5.1.73-5.el6_6.x86_64                   Wed 08 Jul 2015 02:51:56 AM EDT 
 mysql-libs-5.1.73-5.el6_6.x86_64              Wed 08 Jul 2015 02:51:54 AM EDT 
 jenkins-1.613-1.1.noarch                      Tue 12 May 2015 04:23:18 AM EDT 
 gpg-pubkey-d50582e6-4a3feef6                  Tue 12 May 2015 03:23:00 AM EDT 
 scap-security-guide-0.1.18-3.el6.noarch       Wed 29 Apr 2015 01:26:32 AM EDT


2. 查询特定 RPM 包是否已安装
命令格式:rpm -q package_name
如果是已安装的包,则返回详细包名;否则,返回此包未安装的提示。比如:
清单 4. 查询某 RPM 包是否已安装
[root@server01 ~]# rpm -q mysql-server 
 mysql-server-5.1.73-5.el6_6.x86_64 

注意:实际操作中,请确认 package_name 拼写正确!查询时输错包名,会返回此包未安装的提示信息,常常给系统管理员带来误导。如果不能确定包名,建议使用rpm -qa | grep name的方法,进行尝试查找得到确切的包名。

3. 查询特定 RPM 包的基本信息
命令格式:rpm -qi package_name
这个命令查询到的基本信息包括:包名、版本号、发行号、组群、文件大小、描述等信息。比如:
清单 5. 查询已安装 RPM 包的基本信息
[root@server01 ~]# rpm -qi bash 
 Name       : bash                        
 Relocations : (not relocatable) 
 Version     : 4.1.2                           
 Vendor : Red Hat, Inc. 
 Release     : 29.el6                      
 Build Date : Fri 26 Sep 2014 06:32:15 AM EDT 
 Install Date : Sun 21 Dec 2014 08:52:32 PM EST    
 Build Host : x86-026.build.eng.bos.redhat.com 
 Group      : System Environment/Shells    
 Source RPM : bash-4.1.2-29.el6.src.rpm 
 Size       : 3140846                      
 License : GPLv3+ 
 Signature   : RSA/8, Fri 26 Sep 2014 07:02:48 AM EDT, Key ID 199e2f91fd431d51 
 Packager    : Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla> 
 URL       : http://www.gnu.org/software/bash 
 Summary     : The GNU Bourne Again shell 
 Description : The GNU Bourne Again shell (Bash) is a shell or command language interpreter that is compatible with the Bourne shell (sh). Bash incorporates useful features from the Korn shell (ksh) and the C shell (csh). Most sh scripts can be run by bash without modification.


4. 查询特定 RPM 包的配置文件
命令格式:rpm -qc package_name
当系统管理员要更改软件的配置信息,或者查看配置项来定位程序 bug 时,这个命令就派上用场了。比如,查询 openstack nova 的配置文件:
清单 6. 查询已安装 RPM 包的配置文件
[root@nimbus-bvt-osee-kilo-rh7 ~]# rpm -qc openstack-nova-common 
 /etc/logrotate.d/openstack-nova 
 /etc/nova/api-paste.ini 
 /etc/nova/logging_sample.conf 
 /etc/nova/nova.conf 
 /etc/nova/policy.json 
 /etc/nova/rootwrap.conf 
 /etc/polkit-1/localauthority/50-local.d/50-nova.pkla 
 /etc/polkit-1/rules.d/50-nova.rules 
 /etc/sudoers.d/nova


5. 查询特定 RPM 包的文档文件
命令格式:rpm-qd package_name
一些软件,尤其是大型项目的关键组件,在安装时会同时安装文档文件以方便软件的使用。定位 RPM 文档文件,示例如下:
清单 7. 查询已安装软件包的文档文件
[root@server01 ~]# rpm -qd mysql 
 /usr/share/doc/mysql-5.1.73/COPYING 
 /usr/share/doc/mysql-5.1.73/README 
 /usr/share/doc/mysql-5.1.73/README.mysql-docs 
 /usr/share/doc/mysql-5.1.73/README.mysql-license 
 /usr/share/man/man1/my_print_defaults.1.gz 
 /usr/share/man/man1/mysql.1.gz 
 /usr/share/man/man1/mysql_config.1.gz 
 /usr/share/man/man1/mysql_find_rows.1.gz 
 /usr/share/man/man1/mysql_waitpid.1.gz 
 /usr/share/man/man1/mysqlaccess.1.gz 
 /usr/share/man/man1/mysqladmin.1.gz 
 /usr/share/man/man1/mysqldump.1.gz 
 /usr/share/man/man1/mysqlshow.1.gz 
 /usr/share/man/man1/mysqlslap.1.gz


6. 查询特定 RPM 包安装文件的状态
命令格式:rpm -qs package_name
清单 8. 查询已安装软件包文件状态
[root@server01 ~]# rpm -qs pytz 
 normal        /usr/lib/python2.6/site-packages/pytz 
 missing       /usr/lib/python2.6/site-packages/pytz-2010h-py2.6.egg-info 
 normal        /usr/lib/python2.6/site-packages/pytz/__init__.py 
 normal        /usr/lib/python2.6/site-packages/pytz/__init__.pyc 
 normal        /usr/lib/python2.6/site-packages/pytz/__init__.pyo 
 normal        /usr/lib/python2.6/site-packages/pytz/reference.py 
 normal        /usr/lib/python2.6/site-packages/pytz/reference.pyc 
 normal        /usr/lib/python2.6/site-packages/pytz/reference.pyo 
 normal        /usr/lib/python2.6/site-packages/pytz/tzfile.py 
 normal        /usr/lib/python2.6/site-packages/pytz/tzfile.pyc 
 normal        /usr/lib/python2.6/site-packages/pytz/tzfile.pyo 
 normal        /usr/lib/python2.6/site-packages/pytz/tzinfo.py 
 normal        /usr/lib/python2.6/site-packages/pytz/tzinfo.pyc 
 normal        /usr/lib/python2.6/site-packages/pytz/tzinfo.pyo 
 normal        /usr/share/doc/pytz-2010h 
 normal        /usr/share/doc/pytz-2010h/CHANGES.txt 
 normal        /usr/share/doc/pytz-2010h/LICENSE.txt 
 normal        /usr/share/doc/pytz-2010h/README.txt

RPM 文件状态通常有四种,详细说明见下表:

表 1. RPM 文件的状态
状态 说明
Normal 正常,表明文件未被其他软件包修改过
not installed 未安装,表明文件未安装
Replaced 已替换,表明文件已被其他软件包修改替换过,不再是原先的文件
net shared 网络共享,表明文件处于网络共享状态


7. 列出特定 RPM 包已安装的所有文件
命令格式:rpm -ql package_name
软件源码中的一些文件是需要安装到系统中的,我们可以使用这个命令来确认安装文件位置是否正确、内容是否缺失等。比如,查询 openstack-glance 安装在系统中的文件:
清单 9. 列出 RPM 包安装在系统中的所有文件
[root@nimbus-bvt-osee-kilo-rh7 ~]# rpm -ql openstack-glance 
 /etc/glance 
 /etc/glance/glance-api-paste.ini 
 /etc/glance/glance-api.conf 
 /etc/glance/glance-cache.conf 
 /etc/glance/glance-registry-paste.ini 
 /etc/glance/glance-registry.conf 
 /etc/glance/glance-scrubber.conf 
 /etc/glance/policy.json 
 /etc/glance/schema-image.json 
 /etc/logrotate.d/openstack-glance 
 /usr/bin/glance-api 
 /usr/bin/glance-cache-cleaner 
 /usr/bin/glance-cache-manage 
 /usr/bin/glance-cache-prefetcher 
 /usr/bin/glance-cache-pruner 
 /usr/bin/glance-control 
 /usr/bin/glance-index 
 # The following lines are omitted

注意:该命令仅适用于已安装的 RPM 包。对于尚未安装的包,如果我们想知道其中包含哪些文件,可以使用 rpm2cpio 命令查看。
命令格式:rpm2cpio package_name.rpm | cpio -t
查看未安装的 RPM 包中的文件,示例如下:
清单 10. 使用 rpm2cpio 命令查询未安装的 RPM 包含有的文件
[root@server01 rpmbuild-python-passlib]# ll RPMS/noarch/ 
 total 488 
 -rw-r--r-- 1 root root 497772 Sep 25 22:58 python-passlib-1.6.5-1.ibm.noarch.rpm 
[root@server01 noarch]# rpm -ql python-passlib 
 package python-passlib is not installed 
[root@server01 noarch]# rpm2cpio python-passlib-1.6.5-1.ibm.noarch.rpm | cpio -t 
 ./usr/lib/python2.7/site-packages/passlib 
 ./usr/lib/python2.7/site-packages/passlib-1.6.5-py2.7.egg-info 
 ./usr/lib/python2.7/site-packages/passlib-1.6.5-py2.7.egg-info/PKG-INFO 
 ./usr/lib/python2.7/site-packages/passlib-1.6.5-py2.7.egg-info/SOURCES.txt 
 ./usr/lib/python2.7/site-packages/passlib-1.6.5-py2.7.egg-info/dependency_links.txt 
 ./usr/lib/python2.7/site-packages/passlib-1.6.5-py2.7.egg-info/pbr.json 
 ./usr/lib/python2.7/site-packages/passlib-1.6.5-py2.7.egg-info/top_level.txt 
 ./usr/lib/python2.7/site-packages/passlib-1.6.5-py2.7.egg-info/zip-safe 
 ./usr/lib/python2.7/site-packages/passlib/__init__.py 
 ./usr/lib/python2.7/site-packages/passlib/_setup 
 ./usr/lib/python2.7/site-packages/passlib/_setup/__init__.py 
 ./usr/lib/python2.7/site-packages/passlib/_setup/docdist.py 
 ./usr/lib/python2.7/site-packages/passlib/_setup/stamp.py 
 # The following lines are omitted


8. 查询系统中某文件是属于哪个 RPM 包
命令格式:rpm -ql file_name
我们知道 Linux 系统中,python 的安装文件放在 /var/lib/python*/site-packages/ 目录下,如果你突然对其中的某个文件的来源很好奇,可以用这个命令来查询它是属于哪一个 RPM 包的。示例如下:
清单 11. 查询某个文件是源自哪个 RPM 包
[root@nimbus-bvt-osee-kilo-rh7 site-packages]# pwd 
 /usr/lib/python2.7/site-packages 
[root@nimbus-bvt-osee-kilo-rh7 site-packages]# rpm -qf WSME-0.6-py2.7-nspkg.pth 
 python-wsme-0.6-2.ibm.el7.noarch


9. 查询 RPM 包安装、卸载前后的脚本
命令格式:rpm -q --scripts package_name
通常,RPM 包可以在安装、卸载前后做些特定的操作,比如:在安装 RPM 前进行冲突检测、创建用户和组等操作;在安装 RPM 后根据软件需要启动服务或修改文件属性或配置等工作。示例如下:
清单 12. 显示软件包安装、卸载前后运行的脚本
[root@server01 ~]# rpm -q --scripts mysql-server 
 preinstall scriptlet (using /bin/sh): 
 /usr/sbin/groupadd -g 27 -o -r mysql >/dev/null 2>&1 || : 
 /usr/sbin/useradd -M -N -g mysql -o -r -d /var/lib/mysql -s /bin/bash -c "MySQL Server" -u 27 mysql >/dev/null 2>&1 || : 
 postinstall scriptlet (using /bin/sh): 
 if [ $1 = 1 ]; then 
    /sbin/chkconfig --add mysqld 
 fi 
 /bin/chmod 0755 /var/lib/mysql 
 /bin/touch /var/log/mysqld.log 
 preuninstall scriptlet (using /bin/sh): 
 if [ $1 = 0 ]; then 
    /sbin/service mysqld stop >/dev/null 2>&1 
    /sbin/chkconfig --del mysqld 
 fi 
 postuninstall scriptlet (using /bin/sh): 
 if [ $1 -ge 1 ]; then 
    /sbin/service mysqld condrestart >/dev/null 2>&1 || : 
 fi


10. 查看 RPM 包的修改历史
命令格式:rpm -q --changelog package_name
查看修改历史,有助于我们了解软件包的功能,特别是在决定修改、增删 patch 的时候,研究 changelog 可以帮助我们做出正确的决定。查看 RPM 包修改历史,示例如下:
清单 13. 查看软件包的修改历史
[root@nimbus-bvt-osee-kilo-rh7 ~]# rpm -q --changelog python-oslo-db 
 * Mon Mar 23 2015 Gang Xu <xugangsh@cn.ibm.com> - 1.7.1-1.ibm 
 - Fix rtc 197582 to update to 1.7.1 in Kilo 


 * Sun Mar 08 2015 Gang Xu <xugangsh@cn.ibm.com> - 1.5.0-3.ibm 
 - Fix rtc 196366 to add one patch to remove import testresources and 
 - testscenarios in oslo.db 1.5.0 

 * Fri Mar 06 2015 Wen Jianjiao <wenjianj@cn.ibm.com> - 1.5.0-1.ibm 
 - Update dependency version since oslo.db requirements.txt changed 
 - Related RTC 196366 
 # The following lines are omitted


11. 列出特定组群已安装的 RPM 包
命令格式:rpm -qg group_name
RPM 包的基本信息中有一项是组(Group),它定义了 RPM 包所属的类别。我们可以使用 rpm 命令查询定义在某个组下的全部 RPM 包。比如,列出系统中安装的应用程序数据库(Applications/Databases)相关的 RPM 包。
清单 14. 查询某个组群里的 RPM 包
[root@server01 ~]# rpm -qg Applications/Databases 
 sqlite-3.6.20-1.el6.x86_64 
 db4-utils-4.7.25-18.el6_4.x86_64 
 postgresql-libs-8.4.20-2.el6_6.x86_64 
 postgresql-8.4.20-2.el6_6.x86_64 
 mysql-libs-5.1.73-5.el6_6.x86_64 
 mysql-5.1.73-5.el6_6.x86_64 
 mysql-server-5.1.73-5.el6_6.x86_64 
 mysql-devel-5.1.73-5.el6_6.x86_64

通常,RPM 可以分为这几大类:娱乐(Amusement)、开发(Development)、文档(Document)、硬件(Hardware)、综合包(Metapackages)、多媒体(Multimedia)、生产力(Productivity)和系统(System)。
清单 15. RPM 常见 Group
 Amusements/Games 
 Amusements/Graphics 
 Applications/Archiving 
 Applications/Communications 
 Applications/Databases 
 Applications/Editors 
 Applications/Emulators 
 Applications/Engineering 
 Applications/File 
 Applications/Internet 
 Applications/Multimedia 
 Applications/Productivity 
 Applications/Publishing 
 Applications/System 
 Applications/Text 
 Development/Debuggers 
 Development/Languages 
 Development/Libraries 
 Development/System 
 Development/Tools 
 Documentation 
 System Environment/Base 
 System Environment/Daemons 
 System Environment/Kernel 
 System Environment/Libraries 
 System Environment/Shells 
 User Interface/Desktops 
 User Interface/X 
 User Interface/X Hardware Support

RPM 包依赖关系查询

  Linux 系统中,RPM 之间往往存在依赖关系,即一个软件可能应用到其他软件提供的某些功能。RPM 依赖机制,极大地减少了软件系统的冗余,且方便了软件包的版本升级、安装和卸载、冲突检查等,从而有利于系统的维护和管理。
  RPM 在描述软件包之间依赖关系时,使用了一个术语:能力(capability)。"能力"可理解为软件功能的一种抽象,定义每个 RPM 包会提供一种或多种"能力",某些 RPM 包会依赖其他包提供的"能力"。
  RPM Database 通过记录已安装的软件包所依赖的和提供的"能力"信息,来表示软件之间的依赖关系。在安装某个 RPM 包时,系统会自动检测该包所依赖的"能力"是否已安装,如果是的则可以安装该包。成功安装后,该包提供的"能力"会被保存至 RPM Database。如果系统中缺少任何其依赖的"能力",则提示错误信息无法安装;在卸载某个 RPM 包时,系统会自动检测该包所提供的"能力"是否仍被其他 RPM 包使用,如果尚被其他 RPM 包依赖,则无法卸载。这一小节中,我们介绍如何查询 RPM Database 中记录的 RPM 包和"能力"之间的依赖、供给关系。

1. 查询特定 RPM 包依赖哪些"能力"
命令格式:rpm -q query_options --requires package_namee
大多数情况下,"能力"用文件名或者软件包的名字表示。上面的命令将列出软件包依赖的所有"能力",比如:
清单 16. 查询 RPM 包依赖的“能力”
[root@nimbus-bvt-osee-kilo-rh7 ~]# rpm -q --requires python-keystoneclient 
 /usr/bin/python 
 python(abi) = 2.7 
 python-argparse 
 python-iso8601 >= 0.1.9 
 python-keyring 
 python-netaddr >= 0.7.12 
 python-oslo-config >= 1:1.9.0 
 python-oslo-i18n >= 1.3.0 
 python-oslo-serialization >= 1.2.0 
 python-oslo-utils >= 1.2.0 
 python-pbr >= 0.6 
 python-pbr < 1.0 
 python-prettytable > 0.7 
 python-prettytable < 0.8 
 python-requests >= 2.2.0 
 python-six >= 1.9.0 
 python-stevedore >= 1.1.0 
 rpmlib(CompressedFileNames) <= 3.0.4-1 
 rpmlib(FileDigests) <= 4.6.0-1 
 rpmlib(PartialHardlinkSets) <= 4.0.4-1 
 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 
 rpmlib(PayloadIsXz) <= 5.2-1


2. 查询特定 RPM 包提供哪些"能力"
命令格式:rpm -q query_options --provides package_name
RPM 包会对外提供某些"能力",比如:
清单 17. 查询 RPM 包提供的“能力”
[root@nimbus-bvt-osee-kilo-rh7 ~]# rpm -q --provides python-six 
 python-six = 1.9.0-1.ibm.el7 

[root@nimbus-bvt-osee-kilo-rh7 ~]# rpm -q --provides bash 

 /bin/bash 
 /bin/sh 
 bash = 4.2.46-12.el7 
 bash(x86-64) = 4.2.46-12.el7 
 config(bash) = 4.2.46-12.el7

通常"能力"与包名相同,我们也可以在 spec 文件中指定 RPM 提供哪些能力。
语法格式:Provides: capability

3. 查询依赖某种"能力"的 RPM 包
命令格式:rpm -q query_options --whatrequires capability
这个命令可以查询到所有依赖该"能力"的 RPM 包,比如:
清单 18. 查询依赖某“能力”的 RPM 包
[root@nimbus-bvt-osee-kilo-rh7 ~]# rpm -q --whatrequires openssl 
 perl-IO-Socket-SSL-1.94-3.el7.noarch 
 unbound-libs-1.4.20-19.el7.x86_64 
 python-cryptography-0.8.1-1.ibm.el7.x86_64 
 python-nova-2015.1.1.1-201509142203.ibm.el7.140.noarch 
 openvswitch-2.3.0-3.ibm.el7.x86_64

卸载 RPM 包时,如果其提供的"能力"被其他的 RPM 包所依赖,则卸载命令会生成一个错误信息,最终无法卸载此包。比如:
清单 19. openssl 被其他 RPM 包依赖,卸载失败
[root@nimbus-bvt-osee-kilo-rh7 ~]# rpm -e openssl 
 error: Failed dependencies: 
        openssl >= 0.9.8 is needed by (installed) 
         perl-IO-Socket-SSL-1.94-3.el7.noarch 
        openssl >= 0.9.8g-12 is needed by (installed) 
         unbound-libs-1.4.20-19.el7.x86_64 
        openssl is needed by (installed) 
        python-cryptography-0.8.1-1.ibm.el7.x86_64 
        openssl is needed by (installed) 
        python-nova-2015.1.1.1-201509142203.ibm.el7.140.noarch 
        openssl is needed by (installed) 
        openvswitch-2.3.0-3.ibm.el7.x86_64 
    /usr/bin/openssl is needed by (installed) 
     authconfig-6.2.8-9.el7.x86_64

此时,如仍需卸载,可以加上参数 --nodeps(不考虑依赖关系)来强制卸载。
命令格式:rpm -e --nodeps package_name
注意:强制卸载可能导致系统瘫痪,请慎用此命令!

4. 查询提供某种"能力"的 RPM 包
命令格式:rpm -q query_options --whatprovides capability
现在,我们用这个命令来验证上面提到的 openssl "能力"确实由 openssl RPM 包提供。
清单 20. 查询提供某“能力”的 RPM 包
[root@nimbus-bvt-osee-kilo-rh7 ~]# rpm -q --whatprovides openssl 
 openssl-1.0.1e-42.el7.x86_64

提示:一般情况下,一种"能力"由一个 RPM 提供,如果多个 RPM 都提供同一种"能力",则可能产生冲突(conflicts)。

RPM 包的验证

  RPM Database 不仅提供了 RPM 包的查询功能,还提供了对已安装的 RPM 包进行验证的功能。通过验证,我们可以很清楚地知道一个文件变动了什么,这是 RPM 的聪明之处。我们来介绍几个常用的验证命令。

1. 验证某个 RPM 包的状态
命令格式:rpm -V package_name
校验时,若发现文件丢失,RPM 将输出"missing 文件名"。若有属性方面错误,RPM 将用表 2. 中的属性代码输出错误类型。
表 2. RPM 校验属性说明
代码 含义
S 表示文件大小
M 表示文件权限
5 表示 MD5 校验和
D 表示主从设备号
L 表示符号链接
U 表示属主
G 表示属组
T 表示最后修改时间

如果文件某项属性正常,则会显示点(.)字符,否则显示相应的表示字符。示例如下:
清单 21. 验证某个 RPM 包
[root@server01 ~]# rpm -V pytz 
 missing     /usr/lib/python2.6/site-packages/pytz-2010h-py2.6.egg-info 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/__init__.py 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/__init__.pyc 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/__init__.pyo 
 .......T.    /usr/lib/python2.6/site-packages/pytz/reference.py 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/reference.pyc 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/tzfile.py 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/tzfile.pyc 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/tzinfo.py 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/tzinfo.pyc 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/tzinfo.pyo


2. 验证系统中所有的 RPM 包
命令格式:rpm -Va
使用这个命令,我们可以对系统中所有 RPM 文件做一个全面检查。示例如下:
清单 22. 验证系统中所有 RPM 包
[root@server01 ~]# rpm -Va 
 S.5....T.  c /etc/rsyslog.conf 
 SM5....T.  c /etc/sysconfig/rhn/up2date 
 S.5....T.    /usr/lib/jenkins/jenkins.war 
 prelink: /usr/bin/certutil: at least one of file's
  dependencies has changed since prelinking 
 S.?......    /usr/bin/certutil 
 prelink: /usr/bin/cmsutil: at least one of file's 
 dependencies has changed since prelinking 
 S.?......    /usr/bin/cmsutil 
 prelink: /usr/bin/crlutil: at least one of file's 
 dependencies has changed since prelinking 
 S.?......    /usr/bin/crlutil 
 # The following lines are omitted


3. 验证某个组的 RPM 包
命令格式:rpm -Vg group_name
当不必要对整个系统做检查,只需验证某类别的 RPM 文件状态时,我们可以使用这个命令。比如,验证 Development/Lanuages 组下面的 RPM 文件状态:
清单 23. 验证某个组的 RPM 包
[root@server01 ~]# rpm -Vg Development/Languages 
 missing     /usr/lib/python2.6/site-packages/pytz-2010h-py2.6.egg-info 
 S.5....T.   /usr/lib/python2.6/site-packages/pytz/__init__.py 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/__init__.pyc 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/__init__.pyo 
 .......T.    /usr/lib/python2.6/site-packages/pytz/reference.py 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/reference.pyc 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/tzfile.py 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/tzfile.pyc 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/tzinfo.py 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/tzinfo.pyc 
 S.5....T.    /usr/lib/python2.6/site-packages/pytz/tzinfo.pyo


RPM Database 备份与恢复

  经过上面的讲述,我们不难发现 RPM Database 在系统中的重要作用。一旦 RPM Database 遭到损坏,轻则可能导致系统中已安装的 RPM 无法使用,重则导致整个系统的瘫痪。在这一小节中,我们来介绍 RPM Database 的基本结构,以及如何对其备份和恢复。

1.RPM Database 基本结构
  默认情况下,RPM Database 存放在 /var/lib/rpm 目录,除了 __db.00* 是数据文件外,其他文件都属于 Berkeley DB 格式。
清单 24. RPM Database 结构
[root@server01 ~]# file /var/lib/rpm/* 
 /var/lib/rpm/Basenames:      Berkeley DB (Hash, version 9, native byte-order) 
 /var/lib/rpm/Conflictname:   Berkeley DB (Hash, version 9, native byte-order) 
 /var/lib/rpm/__db.001:       Applesoft BASIC program data 
 /var/lib/rpm/__db.002:       386 pure executable 
 /var/lib/rpm/__db.003:       386 pure executable not stripped 
 /var/lib/rpm/__db.004:       386 pure executable 
 /var/lib/rpm/Dirnames:       Berkeley DB (Btree, version 9, native byte-order) 
 /var/lib/rpm/Filedigests:    Berkeley DB (Hash, version 9, native byte-order) 
 /var/lib/rpm/Group:          Berkeley DB (Hash, version 9, native byte-order) 
 /var/lib/rpm/Installtid:     Berkeley DB (Btree, version 9, native byte-order) 
 /var/lib/rpm/Name:           Berkeley DB (Hash, version 9, native byte-order) 
 /var/lib/rpm/Obsoletename:   Berkeley DB (Hash, version 9, native byte-order) 
 /var/lib/rpm/Packages:       Berkeley DB (Hash, version 9, native byte-order) 
 /var/lib/rpm/Providename:    Berkeley DB (Hash, version 9, native byte-order) 
 /var/lib/rpm/Provideversion: Berkeley DB (Btree, version 9, native byte-order) 
 /var/lib/rpm/Pubkeys:        Berkeley DB (Hash, version 9, native byte-order) 
 /var/lib/rpm/Requirename:    Berkeley DB (Hash, version 9, native byte-order) 
 /var/lib/rpm/Requireversion: Berkeley DB (Btree, version 9, native byte-order) 
 /var/lib/rpm/Sha1header:     Berkeley DB (Hash, version 9, native byte-order) 
 /var/lib/rpm/Sigmd5:         Berkeley DB (Hash, version 9, native byte-order) 
 /var/lib/rpm/Triggername:    Berkeley DB (Hash, version 9, native byte-order)

  这些文件对应不同的 RPM 查询类型,比如,上文曾提到过的包名查询命令 rpm -q package_name就是通过 /var/lib/rpm/Name文件得到的。如果这个文件受到损坏或缺失,则 rpm -q package_name命令无法正常工作。举个例子,我们先将 Name 文件移走,然后查询系统中某个已安装的包,则无法找到该包。
清单 25. 破坏 RPM Database 文件,则 RPM 查询命令失败
[root@server01 rpm]# rpm -q perl 
 perl-5.10.1-136.el6_6.1.x86_64 
[root@server01 rpm]# pwd 
 /var/lib/rpm 
 [root@server01 rpm]# mv Name .. 
 [root@server01 rpm]# ll |grep Name 
 [root@server01 rpm]# rpm -q perl 
 package perl is not installed


2.RPM Database 的备份
  RPM Database 关乎重大,系统管理员一定要对其进行备份!备份的方法十分简单,将数据库文件打包保存即可。
命令格式:tar cf rpmdb_backup.tar /var/lib/rpm
清单 26. 对 RPM Database 进行备份
[root@server01 ~]# tar cf rpmdb_backup.tar /var/lib/rpm 
 tar: Removing leading `/' from member names 
[root@server01 ~]# ll |grep rpmdb_backup 
 -rw-r--r--   1 root root 141004800 Sep 29 07:44 rpmdb_backup.tar

系统管理员,针对实际需要可以结合 at、crontab 等命令定期对 RPM Database 进行备份。

3.RPM Database 的恢复
命令格式:rpm --rebuild
当 RPM Database 损坏时,我们可以使用重建数据库命令对其进行恢复。
注意:在使用重建命令恢复数据库前,一定先要对原有数据库文件进行备份!
举一个常见的数据库损坏的例子:Error: rpmdb open failed
清单 27. RPM Database Error: rpmdb open failed
[root@server01 install]# rpm -q mysql 
 error: db5 error(-30969) from dbenv->open: 
  BDB0091 DB_VERSION_MISMATCH: Database environment version mismatch 
 error: cannot open Packages index using db5 -  (-30969) 
 error: cannot open Packages database in /var/lib/rpm 
 error: db5 error(-30969) from dbenv->open: 
 BDB0091DB_VERSION_MISMATCH: Database environment version mismatch 
 error: cannot open Packages database in /var/lib/rpm 
 package mysql is not installed

恢复 RPM Database 前,一定先将原有数据进行备份,然后再使用恢复命令!
通常,恢复方法有下面三种:
只移除 /var/lib/rpm/__db* 文件,然后执行 rpm --rebuilddb命令
当上面的方法没能恢复数据库时,转移 /var/lib/rpm 文件夹,然后执行 rpm --rebuilddb命令
当前面两个方法都没奏效时,则表示情况比较严重,需要重新创建 RPM 数据库,再进行重建数据库操作。首先,选择一个目录创建新的数据库,执行 rpm --initdb --dbpath new_db_path;;然后,执行重构数据库命令:rpm --rebuilddb
针对清单 27. 中的错误,我们采用下面的恢复方法:
清单 28. RPM Database 恢复举例
[root@server01 ~]# cp -r /var/lib/rpm/ ~/rpm-db-backup 
[root@server01 ~]# rpm – rebuilddb 
[root@server01 ~]# rpm -q mysql 
 mysql-5.1.73-5.el6_6.x86_64


结束语

  RPM 使得 Linux 系统软件管理变得十分便利,除了 RPM 提供的自动安装、卸载、升级功能极大地减轻了开发人员和系统管理员的工作量外,RPM 还提供了强大的查询和验证功能。本文围绕 RPM Database,结合实际的应用场景,介绍了 RPM 基本信息查询、RPM 依赖关系原理、RPM 验证和 RPM 数据库备份与恢复等内容。希望通过本文的阅读,对您工作中遇到的 RPM 软件包相关问题有所帮助。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值