Jak naprawić błędy aktualizacji Ubuntu: Kompletny przewodnik rozwiązywania problemów
System zarządzania pakietami APT w Ubuntu jest jednym z najbardziej niezawodnych w ekosystemie Linux, ale nie jest odporny na awarie. Gdy `apt-get upgrade`, `apt-get dist-upgrade` lub `do-release-upgrade` zgłasza błąd, główna przyczyna niemal zawsze należy do jednej z pięciu kategorii: przestarzały lub uszkodzony indeks pakietów, nierozwiązane łańcuchy zależności, przestarzały plik blokady pozostawiony przez proces, który uległ awarii, niewystarczające miejsce na dysku na partycji głównej lub częściowo skonfigurowany pakiet pozostawiony w uszkodzonym stanie przez poprzednią przerwaną transakcję.
Ten przewodnik zapewnia systematyczny, inżynierski przepływ pracy diagnostycznej umożliwiający identyfikację i trwałe rozwiązanie każdej głównej klasy błędów aktualizacji Ubuntu — w tym przypadków brzegowych, które typowe poradniki rutynowo pomijają.
Zrozumienie, co tak naprawdę idzie nie tak podczas aktualizacji Ubuntu
Zanim zaczniesz uruchamiać polecenia na ślepo, warto zrozumieć wewnętrzną mechanikę. Gdy wywołujesz `sudo apt-get upgrade`, APT wykonuje przebieg rozwiązywania zależności względem lokalnej pamięci podręcznej pakietów w `/var/lib/apt/lists/`. Jeśli ta pamięć podręczna jest przestarzała, zniekształcona lub niezsynchronizowana ze skonfigurowanymi repozytoriami w `/etc/apt/sources.list` i `/etc/apt/sources.list.d/`, resolver albo całkowicie zawodzi, albo proponuje niespójny zestaw pakietów.
Warstwa dpkg znajdująca się pod APT utrzymuje własną bazę danych stanu w `/var/lib/dpkg/`. Jeśli poprzednia instalacja lub aktualizacja została przerwana — przez awarię zasilania, zerwanie sesji SSH lub ręczne `Ctrl+C` — dpkg może pozostawić jeden lub więcej pakietów w stanie `half-installed` lub `triggers-awaiting`. APT nie może kontynuować, dopóki stan dpkg nie będzie czysty.
Pięć głównych przyczyn w skrócie
| Główna przyczyna | Objaw | Podstawowa naprawa |
|---|
| — | — | — |
|---|
| Przestarzały indeks pakietów | „404 Not Found” dla adresów URL pakietów | `apt-get update` |
|---|
| Uszkodzone/niespełnione zależności | „Unmet dependencies” lub „held broken packages” | `apt-get install -f` |
|---|
| Przestarzały plik blokady | „Could not get lock /var/lib/dpkg/lock” | Ręczne usunięcie plików blokady |
|---|
| Niewystarczające miejsce na dysku | „No space left on device” | Zwolnienie miejsca na partycji `/` |
|---|
| Częściowo skonfigurowany pakiet | „dpkg was interrupted” | `dpkg –configure -a` |
|---|
Rozwiązanie 1: Odświeżenie indeksu pakietów i przeprowadzenie pełnej aktualizacji
To jest prawidłowy pierwszy krok w każdym przepływie pracy diagnostycznej. Zawsze uruchamiaj `update` przed `upgrade` — nie są one wymienne.
“`bash
sudo apt-get update
sudo apt-get upgrade
“`
Co faktycznie robi każde polecenie:
- `apt-get update` — Pobiera świeże metadane pakietów z każdego repozytorium zdefiniowanego w `sources.list`. Nie instaluje niczego. Nadpisuje pliki indeksu w `/var/lib/apt/lists/`.
- `apt-get upgrade` — Rozwiązuje i instaluje nowsze wersje wszystkich aktualnie zainstalowanych pakietów. Nigdy nie usunie zainstalowanego pakietu ani nie zainstaluje nowego w celu spełnienia zależności — jest to celowe ograniczenie bezpieczeństwa.
Jeśli `apt-get upgrade` jest wstrzymany przez pakiety wymagające nowych zależności lub usunięcia konfliktujących, przejdź do:
“`bash
sudo apt-get dist-upgrade
“`
`dist-upgrade` używa bardziej agresywnego resolvera, który może instalować nowe pakiety i usuwać przestarzałe w celu spełnienia grafu zależności. Jest to właściwe narzędzie do aktualizacji wydań punktowych w ramach tej samej wersji Ubuntu (np. z 22.04.1 do 22.04.4).
Kluczowa kwestia: Na serwerach produkcyjnych zawsze przeglądaj plan `dist-upgrade` przed potwierdzeniem. Uruchom najpierw `apt-get dist-upgrade –dry-run`, aby zobaczyć dokładnie, co zostanie zainstalowane, zaktualizowane lub usunięte bez dotykania systemu.
Rozwiązanie 2: Naprawianie uszkodzonych i niespełnionych zależności
Uszkodzony stan zależności jest jedną z najczęstszych przyczyn niepowodzenia aktualizacji w trakcie procesu. Kanoniczne rozwiązanie to:
“`bash
sudo apt-get install -f
“`
Flaga `-f` (`–fix-broken`) instruuje APT, aby próbował naprawić uszkodzony graf zależności poprzez pobieranie i instalowanie brakujących zależności lub usuwanie pakietów, których nie można spełnić. Po zakończeniu uruchom ponownie aktualizację.
Kiedy `-f` nie wystarczy: Jeśli ręcznie zainstalowałeś pakiety `.deb` spoza oficjalnych repozytoriów (powszechna praktyka przy instalowaniu oprogramowania firm trzecich), te pakiety mogą przypinać zależności do określonych wersji, które kolidują z wersjami z repozytoriów. Zidentyfikuj je za pomocą:
“`bash
apt-cache policy <package_name>
dpkg -l | grep "^ii" | grep -v "^ii lib"
“`
Sprawdź wersje „Installed” i „Candidate”. Przypięty pakiet pokaże niższy kandydat niż oferuje repozytorium lub w ogóle żadnego kandydata. Może być konieczne usunięcie konfliktującego pakietu, ukończenie aktualizacji, a następnie ponowna instalacja zgodnej wersji.
Rozwiązanie 3: Ponowna konfiguracja częściowo zainstalowanych pakietów za pomocą dpkg
Jeśli poprzednia aktualizacja została przerwana, baza danych stanu dpkg będzie zawierać pakiety oznaczone jako `half-configured` lub `half-installed`. APT odmawia kontynuowania, dopóki te nie zostaną rozwiązane.
“`bash
sudo dpkg –configure -a
“`
Flaga `-a` oznacza „wszystkie” — dpkg spróbuje uruchomić skrypty konfiguracji poinstalacyjnej (`postinst`) dla każdego pakietu pozostawionego w niekompletnym stanie. Często rozwiązuje to błędy takie jak:
“`
dpkg was interrupted, you must manually run 'sudo dpkg –configure -a' to correct the problem.
“`
Natychmiast po tym wykonaj świeżą aktualizację indeksu i ponów próbę aktualizacji:
“`bash
sudo apt-get update && sudo apt-get upgrade
“`
Przypadek brzegowy — uszkodzona baza danych dpkg: W rzadkich scenariuszach sama baza danych dpkg ulega uszkodzeniu (najczęściej po awarii dysku lub błędzie systemu plików). Objawy obejmują `dpkg: error: parsing file '/var/lib/dpkg/status'`. Procedura odzyskiwania polega na przywróceniu z kopii zapasowej, którą dpkg automatycznie utrzymuje w `/var/backups/dpkg.status*`. Skopiuj najnowszą kopię zapasową nad uszkodzony plik stanu:
“`bash
sudo cp /var/backups/dpkg.status.0 /var/lib/dpkg/status
sudo dpkg –configure -a
“`
Rozwiązanie 4: Usuwanie przestarzałych plików blokady
APT i dpkg używają plików blokady, aby zapobiec uszkodzeniu bazy danych przez równoczesne operacje na pakietach. Gdy proces trzymający blokadę ulega awarii lub zostaje zabity, plik blokady pozostaje na dysku. Każde kolejne wywołanie APT zakończy się niepowodzeniem z komunikatem:
“`
E: Could not get lock /var/lib/dpkg/lock-frontend – open (11: Resource temporarily unavailable)
“`
Przed usunięciem plików blokady zawsze sprawdź, czy żaden prawidłowy proces ich nie trzyma:
“`bash
sudo lsof /var/lib/dpkg/lock-frontend
sudo lsof /var/lib/dpkg/lock
sudo lsof /var/cache/apt/archives/lock
“`
Jeśli `lsof` nie zwraca żadnych danych wyjściowych, blokada jest przestarzała i można ją bezpiecznie usunąć:
“`bash
sudo rm /var/lib/dpkg/lock-frontend
sudo rm /var/lib/dpkg/lock
sudo rm /var/cache/apt/archives/lock
sudo dpkg –configure -a
sudo apt-get update
“`
Ostrzeżenie: Nigdy nie usuwaj plików blokady, gdy inny proces `apt`, `apt-get`, `dpkg` lub `unattended-upgrades` jest aktywnie uruchomiony. Zrobienie tego na działającym procesie spowoduje uszkodzenie bazy danych pakietów. Jeśli `lsof` pokazuje aktywny PID, poczekaj na zakończenie tego procesu lub zbadaj, dlaczego jest zawieszony, zanim podejmiesz działanie.
Rozwiązanie 5: Zwalnianie miejsca na dysku na partycji głównej
Aktualizacje Ubuntu — szczególnie aktualizacje głównych wersji — wymagają znacznej ilości wolnego miejsca na partycji głównej. Częstym punktem awarii jest zapełnienie `/boot` starymi obrazami jądra, co całkowicie blokuje instalację nowego jądra.
Sprawdź bieżące użycie dysku:
“`bash
df -h
“`
Sprawdź konkretnie, co zajmuje miejsce w `/boot`:
“`bash
du -sh /boot/*
ls /boot/vmlinuz-*
“`
Systematyczna procedura odzyskiwania miejsca:
“`bash
Remove packages installed as dependencies that are no longer needed
sudo apt-get autoremove –purge
Remove cached .deb files from the local package archive
sudo apt-get clean
Remove old kernel images (keeps the two most recent)
sudo apt-get autoremove –purge
“`
Jeśli `/boot` jest nadal pełny po `autoremove`, zidentyfikuj i ręcznie usuń stare jądra. Najpierw znajdź aktualnie działające jądro, aby go nie usunąć:
“`bash
uname -r
“`
Następnie wylistuj zainstalowane jądra i jawnie usuń stare:
“`bash
dpkg -l 'linux-image-*' | grep '^ii'
sudo apt-get purge linux-image-X.X.X-XX-generic
“`
Zastąp ciąg wersji starszą wersją jądra — nigdy tą zwróconą przez `uname -r`.
Jeśli korzystasz ze środowiska VPS Hosting z partycją główną o stałym rozmiarze, ten scenariusz jest szczególnie powszechny. Zapewnienie odpowiedniej alokacji dysku dla VPS od samego początku — lub użycie oddzielnej partycji `/boot` — całkowicie zapobiega tej klasie awarii.
Rozwiązanie 6: Czyszczenie zbędnych pakietów i pamięci podręcznej APT
Nagromadzona pamięć podręczna pakietów i osierocone pakiety obniżają zarówno wydajność systemu, jak i niezawodność aktualizacji.
“`bash
sudo apt-get autoremove
sudo apt-get autoclean
sudo apt-get clean
“`
Różnica między `autoclean` a `clean`:
- `autoclean` usuwa tylko buforowane pliki `.deb` dla pakietów, których nie można już pobrać ze skonfigurowanych repozytoriów (tj. są przestarzałe). Zachowuje buforowane pliki dla aktualnie dostępnych pakietów.
- `clean` usuwa wszystkie buforowane pliki `.deb` bezwarunkowo, niezależnie od tego, czy są nadal dostępne. Użyj tego, gdy potrzebujesz odzyskać maksymalną ilość miejsca na dysku.
Na serwerach, gdzie miejsce na dysku jest zarządzanym zasobem — takich jak Serwery Dedykowane obsługujące wiele usług — automatyzacja okresowego czyszczenia pamięci podręcznej za pomocą zadania cron lub timera systemd jest rozsądną praktyką operacyjną.
Rozwiązanie 7: Ręczne rozwiązywanie konkretnych konfliktów pakietów
Gdy `apt-get upgrade` zgłasza konkretne konflikty pakietów zamiast ogólnego błędu zależności, wymagana jest ukierunkowana interwencja.
“`bash
sudo apt-get upgrade –fix-missing
“`
Ta flaga mówi APT, aby pominął pakiety, których nie można pobrać (np. z powodu tymczasowo niedostępnego mirrora) i zaktualizował wszystko inne. Jest przydatna, gdy pojedynczy niedostępny pakiet blokuje całą aktualizację.
Aby usunąć i ponownie zainstalować konkretny konfliktujący pakiet:
“`bash
sudo apt-get remove –purge <package_name>
sudo apt-get install <package_name>
“`
Użycie `–purge` z `remove` usuwa zarówno pliki binarne pakietu, jak i jego pliki konfiguracyjne, co jest ważne, gdy uszkodzony plik konfiguracyjny jest rzeczywistym źródłem konfliktu.
Identyfikacja dokładnego źródła konfliktu: Gdy APT zgłasza konflikt, komunikat o błędzie zazwyczaj wymienia zaangażowane pakiety. Do głębszej analizy:
“`bash
apt-cache show <package_name>
apt-cache depends <package_name>
apt-cache rdepends <package_name>
“`
`rdepends` (odwrotne zależności) pokazuje, które inne zainstalowane pakiety zależą od danego pakietu — kluczowa informacja przed usunięciem czegokolwiek.
Rozwiązanie 8: Przeprowadzanie aktualizacji głównej wersji za pomocą do-release-upgrade
Aktualizacja między wydaniami Ubuntu LTS (np. z 20.04 Focal do 22.04 Jammy lub z 22.04 do 24.04 Noble) wymaga dedykowanego narzędzia. Używanie samego `apt-get dist-upgrade` do aktualizacji głównej wersji nie jest obsługiwane i spowoduje niespójny system.
Prawidłowa procedura:
“`bash
sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get autoremove
sudo do-release-upgrade
“`
Dlaczego `dist-upgrade` przed aktualizacją ma znaczenie: `do-release-upgrade` sprawdza, czy bieżący system jest w pełni aktualny przed zainicjowaniem przejścia wersji. Jeśli masz wstrzymane pakiety lub nierozwiązane zależności, odmówi kontynuowania. Uruchomienie `dist-upgrade` najpierw zapewnia czystą linię bazową.
Uwagi dotyczące serwerów dla `do-release-upgrade`:
- Na serwerach bez interfejsu graficznego dostępnych przez SSH zawsze uruchamiaj `do-release-upgrade` wewnątrz sesji `tmux` lub `screen`. Jeśli połączenie SSH zostanie zerwane w trakcie aktualizacji, proces będzie kontynuowany w tle zamiast zostać zabity, co pozostawiłoby system w uszkodzonym stanie pośrednim.
- Używaj flagi `-d` tylko podczas aktualizacji do wydania deweloperskiego (jeszcze niestabilnego LTS). W systemach produkcyjnych nigdy nie używaj `-d`.
- Narzędzie będzie monitować o przejrzenie zmian w plikach konfiguracyjnych zmodyfikowanych względem ich wartości domyślnych. Czytaj te monity uważnie — ślepe akceptowanie wersji opiekuna może nadpisać niestandardowe konfiguracje serwera.
“`bash
Start a persistent session before upgrading
tmux new -s upgrade
sudo do-release-upgrade
“`
Jeśli zarządzasz wieloma serwerami Ubuntu — na przykład flotą instancji VPS z cPanel — najpierw przetestuj ścieżkę aktualizacji na węźle nieprodukcyjnym. cPanel i podobne panele sterowania często mają określone okna obsługi wersji Ubuntu, które są opóźnione względem oficjalnego cyklu wydań.
Rozwiązanie 9: Naprawianie problemów z repozytoriami firm trzecich
Często pomijaną przyczyną błędów aktualizacji jest uszkodzone lub niekompatybilne repozytorium PPA (Personal Package Archive) firmy trzeciej. Gdy PPA jest dodane dla jednego wydania Ubuntu i aktualizujesz do następnego, PPA może nie mieć pakietów dla nowej nazwy kodowej wydania, powodując, że `apt-get update` zgłasza błędy takie jak:
“`
E: The repository 'http://ppa.launchpad.net/…' does not have a Release file.
“`
Wylistuj wszystkie skonfigurowane repozytoria:
“`bash
ls /etc/apt/sources.list.d/
cat /etc/apt/sources.list
“`
Tymczasowo wyłącz problematyczne PPA, komentując lub usuwając ich pliki `.list` w `/etc/apt/sources.list.d/`, ukończ aktualizację systemu, a następnie ponownie włącz lub zastąp je wersjami zgodnymi z nowym wydaniem.
“`bash
sudo add-apt-repository –remove ppa:<ppa_name>/<ppa_name>
“`
Rozwiązanie 10: Ponowne uruchomienie w celu wyeliminowania zakłóceń na poziomie procesów
Niektóre błędy aktualizacji są spowodowane stanem w pamięci, a nie problemami na poziomie dysku — na przykład działająca usługa trzymająca uchwyt pliku na bibliotece, którą APT musi zastąpić, lub moduł jądra kolidujący z nowo zainstalowaną wersją.
“`bash
sudo reboot
“`
Po ponownym uruchomieniu wykonaj pełną sekwencję aktualizacji od czystego stanu:
“`bash
sudo apt-get update && sudo apt-get upgrade
“`
Na zdalnych serwerach, gdzie ponowne uruchomienie wiąże się z ryzykiem operacyjnym, użyj `needrestart`, aby zidentyfikować usługi wymagające restartu bez pełnego ponownego uruchomienia systemu:
“`bash
sudo apt-get install needrestart
sudo needrestart
“`
`needrestart` sprawdza działające procesy i identyfikuje te używające przestarzałych bibliotek współdzielonych, umożliwiając restart tylko dotkniętych usług zamiast całego systemu.
Zapobieganie błędom aktualizacji Ubuntu: najlepsze praktyki operacyjne
Reaktywne rozwiązywanie problemów jest konieczne, ale proaktywna higiena systemu eliminuje większość tych awarii, zanim wystąpią.
Lista kontrolna konserwacji dla serwerów Ubuntu:
- Uruchamiaj `sudo apt-get update && sudo apt-get upgrade` regularnie — co najmniej co tydzień dla systemów produkcyjnych.
- Monitoruj miejsce na dysku na `/`, `/boot` i `/var` z progami alertów (85% użycia to rozsądny wyzwalacz).
- Audytuj PPA firm trzecich przed każdym głównym cyklem aktualizacji.
- Zawsze uruchamiaj główne aktualizacje wewnątrz `tmux` lub `screen` na systemach zdalnych.
- Zachowaj migawkę lub kopię zapasową przed każdą operacją `do-release-upgrade`. Na Serwerze Dedykowanym lub VPS oznacza to wykonanie pełnego obrazu dysku lub migawki systemu plików przed zainicjowaniem aktualizacji.
- Testuj procedury aktualizacji w środowisku testowym przed zastosowaniem na produkcji.
- Używaj `unattended-upgrades` tylko do poprawek bezpieczeństwa, nie do pełnych aktualizacji pakietów, aby uniknąć nieoczekiwanych zmian zależności w systemach produkcyjnych.
Dla zespołów zarządzających infrastrukturą webową — w tym środowiskami Współdzielonego Hostingu lub serwerami aplikacji wielodostępnych — ustanowienie udokumentowanego podręcznika aktualizacji zawierającego kroki weryfikacji przed aktualizacją, procedury wycofywania i testy walidacji po aktualizacji jest niezbędną praktyką operacyjną.
Macierz decyzyjna: które rozwiązanie zastosować jako pierwsze
| Komunikat o błędzie | Pierwsze działanie | Drugie działanie |
|---|
| — | — | — |
|---|
| „Could not get lock” | Sprawdź `lsof`, usuń przestarzałe pliki blokady | `dpkg –configure -a` |
|---|
| „Unmet dependencies” | `apt-get install -f` | `dpkg –configure -a` |
|---|
| „No space left on device” | `apt-get autoremove –purge && apt-get clean` | Ręczne usunięcie starych jąder |
|---|
| „dpkg was interrupted” | `dpkg –configure -a` | `apt-get update && apt-get upgrade` |
|---|
| „404 Not Found” dla pakietów | `apt-get update` (sprawdź dostępność mirrora) | Wyłącz uszkodzone PPA |
|---|
| „held broken packages” | `apt-get dist-upgrade –dry-run` | Usuń/ponownie zainstaluj konfliktujący pakiet |
|---|
| Zerwanie SSH podczas aktualizacji | Połącz ponownie i dołącz do sesji `tmux`/`screen` | `dpkg –configure -a` jeśli sesja została utracona |
|---|
FAQ
Dlaczego `apt-get upgrade` pozostawia niektóre pakiety jako „held back”?
Pakiety są wstrzymywane, gdy ich aktualizacja wymagałaby instalacji nowych pakietów lub usunięcia istniejących — działań, których `apt-get upgrade` nie może podejmować zgodnie z projektem. Użyj `apt-get dist-upgrade`, aby rozwiązać wstrzymane pakiety, ale zawsze przeglądaj proponowane zmiany za pomocą `–dry-run` najpierw na systemach produkcyjnych.
Czy bezpieczne jest usuwanie plików blokady z `/var/lib/dpkg/`?
Tylko jeśli żaden proces APT lub dpkg nie jest aktywnie uruchomiony. Zweryfikuj za pomocą `sudo lsof /var/lib/dpkg/lock-frontend` przed usunięciem. Jeśli działający proces trzyma blokadę i usuniesz plik, uszkodzisz bazę danych pakietów, co wymaga ręcznego odzyskiwania z kopii zapasowej stanu dpkg.
Jaka jest różnica między `apt-get upgrade` a `apt-get dist-upgrade`?
`apt-get upgrade` nigdy nie usuwa zainstalowanych pakietów ani nie instaluje nowych w celu rozwiązania zależności — tylko aktualizuje pakiety, które można spełnić bez zmian strukturalnych. `apt-get dist-upgrade` używa inteligentniejszego resolvera, który może instalować nowe pakiety i usuwać przestarzałe. Do aktualizacji wydań punktowych i aktualizacji głównych wersji `dist-upgrade` jest właściwym narzędziem.
Dlaczego `do-release-upgrade` kończy się niepowodzeniem natychmiast po jego uruchomieniu?
Najczęstszym powodem jest to, że bieżący system ma nierozwiązane zależności lub wstrzymane pakiety. Uruchom `sudo apt-get dist-upgrade` i `sudo apt-get autoremove`, aby doprowadzić system do w pełni spójnego stanu przed wywołaniem `do-release-upgrade`. Sprawdź również, czy wszystkie PPA firm trzecich są wyłączone lub zgodne z docelowym wydaniem.
Ile wolnego miejsca na dysku jest wymagane do aktualizacji głównej wersji Ubuntu?
Jako praktyczne minimum potrzebujesz co najmniej 2–3 GB wolnego miejsca na partycji głównej i co najmniej 200–300 MB wolnego miejsca na `/boot`. Rzeczywiste wymaganie zależy od liczby zainstalowanych pakietów. Uruchom `sudo do-release-upgrade` przy systemie spełniającym lub przekraczającym te progi; jeśli miejsce jest ograniczone, uruchom `sudo apt-get autoremove –purge && sudo apt-get clean` bezpośrednio przed zainicjowaniem aktualizacji.
