Corrigindo "Could not get lock" no apt/dpkg
O que significa "Could not get lock"?
Conclusao: apt e dpkg sao projetados para executar um de cada vez, protegidos por arquivos de lock. Este erro significa que outro processo ja segura o lock. Na maioria das vezes, e uma atualizacao automatica em segundo plano.
Quando voce executa algo como apt install, pode encontrar este erro e parar:
$ sudo apt install nginx E: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 1234 (apt) E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?
apt e dpkg podem executar apenas uma instancia de cada vez para nunca corromper o banco de dados de pacotes. Essa exclusao mutua e aplicada com arquivos de lock: enquanto uma operacao esta em andamento, qualquer outro comando falha ao adquirir o lock e imprime este erro.
Portanto nada esta "quebrado" -- voce foi simplesmente recusado porque algo ja esta na fila. Na maioria dos casos, esperar alguns minutos resolve. Apressar-se para excluir os arquivos de lock e a reacao mais perigosa; o primeiro passo correto e ver quem segura o lock.
Premissas (ambiente alvo)
- SO: Ubuntu / distribuicoes baseadas em Debian (qualquer uma que use apt / dpkg)
- Voce pode usar
sudo - Nao faca
rmnos arquivos de lock primeiro (razao explicada abaixo)
Quais arquivos de lock o apt usa?
Conclusao: Nao existe apenas um lock, mas quatro.
lock-frontendcobre todo o frontend,locko banco de dados dpkg,archives/lockdownloads, elists/lockoapt update. O caminho no erro indica em qual estagio travou.
O apt usa arquivos de lock separados para diferentes estagios. O caminho mostrado no erro indica onde esta travado.
| Arquivo de lock | Funcao | Usado durante |
|---|---|---|
/var/lib/dpkg/lock-frontend |
Todo o frontend apt | Quase todas operacoes apt |
/var/lib/dpkg/lock |
O banco de dados dpkg | Descompactacao / configuracao |
/var/cache/apt/archives/lock |
Cache de downloads .deb |
Download de pacotes |
/var/lib/apt/lists/lock |
Listas de pacotes | Durante apt update |
O apt moderno (Ubuntu 18.04+) adquire lock-frontend primeiro. Se o erro menciona lock-frontend, outro apt / dpkg esta segurando todo o frontend.
Os arquivos de lock sao vazios; a exclusao e aplicada com flock (um lock de arquivo), nao pela existencia do arquivo. "O arquivo existe, entao exclua" e o modelo mental errado. Quando o processo que segura sai, o proximo apt funciona normalmente mesmo que o arquivo ainda esteja la.
Por que o lock nao pode ser adquirido?
Conclusao: 90% das vezes outro processo da familia apt esta executando. Se resume a atualizacoes automaticas, o atualizador grafico, um duplo lancamento ou um crash anterior -- e atualizacoes automaticas dominam.
A causa quase sempre se enquadra em um dos quatro padroes.
| Causa | Situacao tipica | Direcao |
|---|---|---|
| Atualizacao automatica em segundo plano | Acabou de iniciar / timer apt-daily disparou |
Esperar |
| Ferramenta grafica de atualizacao | "Software Updater" / packagekit executando | Fechar o GUI |
| apt lancado duas vezes | apt deixado executando em outro terminal | Esperar terminar |
| apt anterior travou | Terminal fechado no meio da instalacao / queda de energia | Comando de recuperacao |
O primeiro e de longe o mais comum. O Ubuntu executa apt-daily.service / apt-daily-upgrade.service em timers que disparam logo apos a inicializacao e em horarios aleatorios, executando apt update ou unattended-upgrades em segundo plano. Executar apt install logo apos provisionar um servidor frequentemente colide com estes.
Como encontro o processo que segura o lock?
Conclusao: Comece com
lsofoufuserpara encontrar qual processo tem o arquivo de lock aberto. O apt moderno tambem imprime o PID no erro. Sabendo o que e (apt / unattended-upgrades / etc.), a correcao se segue.
O primeiro passo e identificar quem segura o lock. Excluir ou matar vem apenas depois disso.
O apt moderno imprime held by process 1234 (apt) no erro. Quando nao o faz, use lsof.
$ sudo lsof /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock /var/cache/apt/archives/lock
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME unattended 1234 root 5uW REG 8,1 0 ... /var/lib/dpkg/lock-frontend
O W na coluna FD significa um lock de escrita. Aqui unattended-upgrades esta segurando. Se voce nao tem lsof, fuser tambem funciona.
$ sudo fuser -v /var/lib/dpkg/lock-frontend
Listar processos da familia apt fornece uma visao mais ampla.
$ ps aux | grep -iE 'apt|dpkg|unattended' | grep -v grep
root 1234 ... /usr/bin/python3 /usr/bin/unattended-upgrade
Se quem segura e unattended-upgrade ou apt-daily, uma atualizacao automatica esta executando -- apenas espere. Se e um duplo lancamento manual de apt, finalize a outra sessao.
E se uma atualizacao automatica for a causa?
Conclusao: Atualizacoes automaticas (unattended-upgrades) terminam em poucos minutos, entao esperar e o melhor. Matar o processo deixa a atualizacao parcialmente aplicada. Pare o servico adequadamente apenas se realmente nao puder esperar.
Se lsof mostra unattended-upgrade, esse processo nao e prejudicial -- esta aplicando atualizacoes de seguranca. Geralmente termina em 1-5 minutos e libera o lock por conta propria.
Para acompanhar o progresso, verifique o status.
$ systemctl status unattended-upgrades $ sudo journalctl -u unattended-upgrades -f
Se nunca terminar, ou voce tiver uma razao real para parar, nao faca kill -9 -- pare adequadamente como servico.
$ sudo systemctl stop unattended-upgrades
kill -9 no meio de uma atualizacao deixa pacotes "descompactados mas nao configurados", o que forca uma recuperacao com dpkg --configure -a depois. Se precisar parar, prefira systemctl stop ou um kill normal (SIGTERM).
Quando e seguro excluir os arquivos de lock?
Conclusao: Excluir arquivos de lock e um ultimo recurso, permitido somente apos confirmar com
lsofque nenhum processo os segura. Excluir enquanto um processo esta executando corrompe o banco de dados dpkg.
Voce vera conselhos para "apenas excluir os arquivos de lock". Isso so e valido como passo final apos confirmar que nenhum apt / dpkg esta executando. Excluir enquanto um processo esta ativo e duas instancias apt reescrevem o banco de dados ao mesmo tempo, quebrando o gerenciamento de pacotes.
Primeiro, confirme que nenhum processo tem os locks abertos.
# Sem saida significa que nenhum processo os segura $ sudo lsof /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock /var/cache/apt/archives/lock /var/lib/apt/lists/lock $ ps aux | grep -iE 'apt|dpkg|unattended' | grep -v grep
Somente quando ambos estiverem vazios (nenhum apt / dpkg executando) voce pode remover os arquivos de lock obsoletos.
$ sudo rm /var/lib/dpkg/lock-frontend $ sudo rm /var/lib/dpkg/lock $ sudo rm /var/cache/apt/archives/lock $ sudo rm /var/lib/apt/lists/lock
Nunca exclua os arquivos de lock enquanto um processo esta executando. O banco de dados dpkg (/var/lib/dpkg/) pode ser corrompido, no pior caso tornando o gerenciamento de pacotes irrecuperavel. Nao faca rm ate lsof e ps confirmarem que nada esta executando.
Como recupero um dpkg interrompido?
Conclusao: Apos liberar o lock, execute
sudo dpkg --configure -a. Ele termina de configurar pacotes deixados "descompactados mas nao configurados", depoisapt-get install -f/apt updaterestaura a consistencia.
Mesmo apos o lock ser liberado, um apt anterior que morreu no meio da operacao pode deixar pacotes semi-instalados. dpkg --configure -a normaliza isso.
$ sudo dpkg --configure -a
Isso reconfigura todos os pacotes que foram descompactados mas ainda nao configurados. Depois repare dependencias quebradas e atualize as listas.
$ sudo apt-get install -f $ sudo apt update
apt-get install -f (--fix-broken) repara pacotes com dependencias quebradas. Quando isso passar, apt install funciona normalmente de novo.
A sequencia padrao de recuperacao sao estes tres, na ordem:
sudo dpkg --configure -a sudo apt-get install -f sudo apt update
Como evitar recorrencia?
Conclusao: Em scripts e automacao, defina
DPkg::Lock::Timeoutpara que o apt espere pelo lock em vez de falhar instantaneamente. Ele tenta novamente pelo numero de segundos dado. Padrao no apt 2.x e posterior.
Para trabalho manual, "esperar a atualizacao automatica terminar" e suficiente. Mas em CI ou scripts de provisionamento, colidir com uma atualizacao automatica e falhar e doloroso. O apt 2.x pode esperar um numero definido de segundos em vez de retornar erro imediatamente.
# Esperar ate 60 segundos pelo lock $ sudo apt-get -o DPkg::Lock::Timeout=60 install nginx
# Esperar indefinidamente (-1) $ sudo apt-get -o DPkg::Lock::Timeout=-1 install nginx
Para automacao que executa apt install logo apos a inicializacao de um servidor, adicionar DPkg::Lock::Timeout sozinho previne a maioria das colisoes de lock com o apt-daily da inicializacao.
O que nao fazer
rmnos arquivos de lock sem verificar se ha um processokill -9em um apt / dpkg que esta atualizando- Executar duas instancias de apt ao mesmo tempo no mesmo servidor
Resumo: checklist
Conclusao: A ordem basica e "identificar -> esperar -> recuperar". Excluir arquivos de lock e ultimo recurso, somente apos confirmar que nenhum processo os segura. Siga essa ordem e voce corrige sem quebrar o dpkg.
- [ ] Identificou quem segura via PID no erro ou
lsof? - [ ] Se e
unattended-upgrade/apt-daily, esperou alguns minutos? - [ ] Verificou que o "Software Updater" / packagekit grafico nao esta executando?
- [ ] Se for matar, evitou
kill -9e usousystemctl stopoukillnormal? - [ ] Confirmou com
lsofepsque nada esta executando antes de excluir locks? - [ ] Se interrompido, recuperou com
dpkg --configure -a->apt-get install -f->apt update? - [ ] Definiu
DPkg::Lock::Timeoutna automacao?