[FrontPage] [TitleIndex] [WordIndex

This is a read-only archived version of wiki.centos.org

清除 yum 失敗後遺留的重複套件

1. 問題

假若 yum 在更新時發生嚴重錯誤例如:ssh 對話在更新時斷線,yum 由於記憶體不足而終止,系統失去電源等,你的系統有可能會停留在一個不確定的狀態,並出現兩組套件。到時候 yum-complete-transaction 及任何 yum 更新都會拒絕執行並投訴有重複套件。

2. 修正概述

你必須進行手動修復來修正這個問題。在開始之先,我們極力建議你最少將 /var/lib/rpm 及 /var/lib/yum 備份,那麼就算在嘗試修復的過程中系統損毀得 更嚴重 時,你仍可以回復到現有的狀況。

更新資訊:看來由 7.6 版開始 package-cleanup 指令新增了一個選項: --removenewestdupes 正正能做到本篇文章嘗試以人手進行的任務。請先以 package-cleanup --cleandupes --removenewestdupes 作為第一步,然後才繼續以下步驟。要是該選項不獲接納,你也許要執行下列指引。否則所須的事情應該已經辦妥,而你可以重新執行 yum update,但今次不要再切斷電源/停用終端機……

3. 舊修正資訊 —— 大概已不再需要

這裡的程序會建立一個重複套件的清單。利用這個清單,我們 單單 從資料庫移除較新套件的記錄。之後,我們便重新執行 yum update 下載新套件及再次更新系統,這樣可確保新版的套件被完全地及正確地安裝。

4. 修正詳情

package-cleanup 指令是 yum-utils 套件的一部份,因此你首先要安裝該套件。安裝後,執行 package-cleanup --dupes --noplugins 便會輸出類似以下的清單,它是我在一台虛擬電腦更新中途「拔掉電源」後所產生的:

[root@localhost ~]# package-cleanup --dupes
Loaded plugins: fastestmirror
nss-tools-3.28.4-8.el7.x86_64
nss-tools-3.28.4-15.el7_4.x86_64
grub2-common-2.02-0.64.el7.centos.noarch
grub2-common-2.02-0.65.el7.centos.2.noarch
wpa_supplicant-2.6-5.el7.x86_64
wpa_supplicant-2.6-5.el7_4.1.x86_64
grub2-tools-extra-2.02-0.65.el7.centos.2.x86_64
grub2-tools-extra-2.02-0.64.el7.centos.x86_64
nss-sysinit-3.28.4-15.el7_4.x86_64
nss-sysinit-3.28.4-8.el7.x86_64
grub2-tools-2.02-0.65.el7.centos.2.x86_64
grub2-tools-2.02-0.64.el7.centos.x86_64
bind-license-9.9.4-50.el7.noarch
bind-license-9.9.4-51.el7.noarch
nss-3.28.4-15.el7_4.x86_64
nss-3.28.4-8.el7.x86_64
kmod-20-15.el7_4.4.x86_64
kmod-20-15.el7.x86_64
systemd-219-42.el7.x86_64
systemd-219-42.el7_4.4.x86_64
selinux-policy-3.13.1-166.el7_4.5.noarch
selinux-policy-3.13.1-166.el7.noarch
grub2-pc-modules-2.02-0.65.el7.centos.2.noarch
grub2-pc-modules-2.02-0.64.el7.centos.noarch
NetworkManager-libnm-1.8.0-11.el7_4.x86_64
NetworkManager-libnm-1.8.0-9.el7.x86_64
NetworkManager-1.8.0-11.el7_4.x86_64
NetworkManager-1.8.0-9.el7.x86_64
nss-softokn-freebl-3.28.3-6.el7.x86_64
nss-softokn-freebl-3.28.3-8.el7_4.x86_64
grub2-pc-2.02-0.65.el7.centos.2.x86_64
grub2-pc-2.02-0.64.el7.centos.x86_64
openssh-server-7.4p1-13.el7_4.x86_64
openssh-server-7.4p1-11.el7.x86_64
systemd-libs-219-42.el7_4.4.x86_64
systemd-libs-219-42.el7.x86_64
cpio-2.11-24.el7.x86_64
cpio-2.11-25.el7_4.x86_64
kmod-libs-20-15.el7.x86_64
kmod-libs-20-15.el7_4.4.x86_64
ncurses-libs-5.9-13.20130511.el7.x86_64
ncurses-libs-5.9-14.20130511.el7_4.x86_64
nss-softokn-3.28.3-8.el7_4.x86_64
nss-softokn-3.28.3-6.el7.x86_64
ncurses-base-5.9-14.20130511.el7_4.noarch
ncurses-base-5.9-13.20130511.el7.noarch
bash-4.2.46-29.el7_4.x86_64
bash-4.2.46-28.el7.x86_64
NetworkManager-wifi-1.8.0-9.el7.x86_64
NetworkManager-wifi-1.8.0-11.el7_4.x86_64
kexec-tools-2.0.14-17.2.el7.x86_64
kexec-tools-2.0.14-17.el7.x86_64
NetworkManager-tui-1.8.0-11.el7_4.x86_64
NetworkManager-tui-1.8.0-9.el7.x86_64
openssh-7.4p1-11.el7.x86_64
openssh-7.4p1-13.el7_4.x86_64
grub2-tools-minimal-2.02-0.64.el7.centos.x86_64
grub2-tools-minimal-2.02-0.65.el7.centos.2.x86_64
NetworkManager-team-1.8.0-11.el7_4.x86_64
NetworkManager-team-1.8.0-9.el7.x86_64
systemd-sysv-219-42.el7_4.4.x86_64
systemd-sysv-219-42.el7.x86_64
binutils-2.25.1-32.base.el7_4.1.x86_64
binutils-2.25.1-31.base.el7.x86_64
selinux-policy-targeted-3.13.1-166.el7_4.5.noarch
selinux-policy-targeted-3.13.1-166.el7.noarch 

持著這份清單,你必須從 rpm 資料庫移除每對重複套件中的 較新版 ,好讓它認為舊版套件仍在系統上。package-cleanup 中有一個 --cleandupes 的選項,但它與安全做法剛剛相反,並且移除舊版套件。問題是你無法確定新版套件的安裝是否正確,因此移除舊記錄雖然能修正重複套件的問題,卻無法保證你的系統是穩定的。

你可以利用 rpm -e --justdb --nodeps $newerpackage 來移除重複的套件 —— 就上述範例而言,指令是 rpm -e --justdb --nodeps nss-tools-3.28.4-15.el7_4.x86_64 grub2-common-2.02-0.65.el7.centos.2.noarch wpa_supplicant-2.6-5.el7_4.1.x86_64 etc etc(請勿盲目地剪貼這個指令,你的套件與版本將會有異)。

5. 潛在問題

請留意較新的套件 不一定 在清單中較遲出現 —— 就好像 selinux-policy-targeted-3.13.1-166.el7_4.5.noarch 是首先被列出的,而它比重複了的 selinux-policy-targeted-3.13.1-166.el7.noarch 還要新 ,而 NetworkManager-1.8.0-11.el7_4.x86_64 比 NetworkManager-1.8.0-9.el7.x86_64 還要新 。因此要將這個步驟自動化並不簡單,而你必須以手動方式建立這個清單……抱歉!

一個較為方便的做法是將 package-cleanup 的輸出導入文字檔,然後利用你慣用的編輯器把 較舊版 的套件名稱從清單中刪除,只剩下較新版的套件名稱。做法:package-cleanup --dupes --noplugins > pcd.txt 然後編輯它,從清單中刪除舊版本,儲存它,然後執行 for p in $(cat pcd.txt); do echo rpm -e --justdb --nodeps $p;done。細心的讀者會發現這樣做只會在終端機列印要執行的指令……你必須去除 echo 才會真正 執行 這些指令。你有責任確保這些指令將會做你所期望的事情,如果出錯的話請勿怪責我!

現在你明白在開始前把 /var/lib/yum 和 /var/lib/rpm 備份的重要性了……你 把它們備份,對嗎?

去除所有重複的套件後,現在你可以重新執行 yum update,但你亦須要修正導致上次更新出錯的原因。要是你透過 ssh 進行更新,但連線有可能被中斷,你可利用 tmux 或 screen 防止 yum 在斷線時被終止。要是你記憶體不足,增添記憶體或調換檔,或在開始前先停止佔用大量記憶體的進程。

Translation of revision 9


2023-09-11 07:23