Corrigindo "Could not get lock" no apt/dpkg
O que significa "Could not get lock"?
Conclusão: apt e dpkg são projetados para executar um de cada vez, protegidos por arquivos de lock. Este erro significa que outro processo já segura o lock. Na maioria das vezes, é uma atualização automática em segundo plano.
Quando você 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 instância de cada vez para nunca corromper o banco de dados de pacotes. Essa exclusão mútua é aplicada com arquivos de lock: enquanto uma operação está em andamento, qualquer outro comando falha ao adquirir o lock e imprime este erro.
Portanto nada está "quebrado" -- você foi simplesmente recusado porque algo já está na fila. Na maioria dos casos, esperar alguns minutos resolve. Apressar-se para excluir os arquivos de lock é a reação mais perigosa; o primeiro passo correto é ver quem segura o lock.
Premissas (ambiente alvo)
- SO: Ubuntu / distribuições baseadas em Debian (qualquer uma que use apt / dpkg)
- Você pode usar
sudo - Não faça
rmnos arquivos de lock primeiro (razão explicada abaixo)
Quais arquivos de lock o apt usa?
Conclusão: Não 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 estágio travou.
O apt usa arquivos de lock separados para diferentes estágios. O caminho mostrado no erro indica onde está travado.
| Arquivo de lock | Função | Usado durante |
|---|---|---|
/var/lib/dpkg/lock-frontend |
Todo o frontend apt | Quase todas operações apt |
/var/lib/dpkg/lock |
O banco de dados dpkg | Descompactação / configuração |
/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 está segurando todo o frontend.
Os arquivos de lock são vazios; a exclusão é aplicada com flock (um lock de arquivo), não pela existência do arquivo. "O arquivo existe, então exclua" é o modelo mental errado. Quando o processo que segura sai, o próximo apt funciona normalmente mesmo que o arquivo ainda esteja lá.
Por que o lock não pode ser adquirido?
Conclusão: 90% das vezes outro processo da família apt está executando. Se resume a atualizações automáticas, o atualizador gráfico, um duplo lançamento ou um crash anterior -- e atualizações automáticas dominam.
A causa quase sempre se enquadra em um dos quatro padrões.
| Causa | Situação típica | Direção |
|---|---|---|
| Atualização automática em segundo plano | Acabou de iniciar / timer apt-daily disparou |
Esperar |
| Ferramenta gráfica de atualização | "Software Updater" / packagekit executando | Fechar o GUI |
| apt lançado duas vezes | apt deixado executando em outro terminal | Esperar terminar |
| apt anterior travou | Terminal fechado no meio da instalação / queda de energia | Comando de recuperação |
O primeiro é de longe o mais comum. O Ubuntu executa apt-daily.service / apt-daily-upgrade.service em timers que disparam logo após a inicialização e em horários aleatórios, executando apt update ou unattended-upgrades em segundo plano. Executar apt install logo após provisionar um servidor frequentemente colide com estes.
Como encontro o processo que segura o lock?
Conclusão: Comece com
lsofoufuserpara encontrar qual processo tem o arquivo de lock aberto. O apt moderno também imprime o PID no erro. Sabendo o que é (apt / unattended-upgrades / etc.), a correção se segue.
O primeiro passo é identificar quem segura o lock. Excluir ou matar vem apenas depois disso.
O apt moderno imprime held by process 1234 (apt) no erro. Quando não 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 está segurando. Se você não tem lsof, fuser também funciona.
$ sudo fuser -v /var/lib/dpkg/lock-frontend
Listar processos da família apt fornece uma visão mais ampla.
$ ps aux | grep -iE 'apt|dpkg|unattended' | grep -v grep
root 1234 ... /usr/bin/python3 /usr/bin/unattended-upgrade
Se quem segura é unattended-upgrade ou apt-daily, uma atualização automática está executando -- apenas espere. Se é um duplo lançamento manual de apt, finalize a outra sessão.
E se uma atualização automática for a causa?
Conclusão: Atualizações automáticas (unattended-upgrades) terminam em poucos minutos, então esperar é o melhor. Matar o processo deixa a atualização parcialmente aplicada. Pare o serviço adequadamente apenas se realmente não puder esperar.
Se lsof mostra unattended-upgrade, esse processo não é prejudicial -- está aplicando atualizações de segurança. Geralmente termina em 1-5 minutos e libera o lock por conta própria.
Para acompanhar o progresso, verifique o status.
$ systemctl status unattended-upgrades $ sudo journalctl -u unattended-upgrades -f
Se nunca terminar, ou você tiver uma razão real para parar, não faça kill -9 -- pare adequadamente como serviço.
$ sudo systemctl stop unattended-upgrades
kill -9 no meio de uma atualização deixa pacotes "descompactados mas não configurados", o que força uma recuperação com dpkg --configure -a depois. Se precisar parar, prefira systemctl stop ou um kill normal (SIGTERM).
Quando é seguro excluir os arquivos de lock?
Conclusão: Excluir arquivos de lock é um último recurso, permitido somente após confirmar com
lsofque nenhum processo os segura. Excluir enquanto um processo está executando corrompe o banco de dados dpkg.
Você verá conselhos para "apenas excluir os arquivos de lock". Isso só é válido como passo final após confirmar que nenhum apt / dpkg está executando. Excluir enquanto um processo está ativo e duas instâncias 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) você 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 está executando. O banco de dados dpkg (/var/lib/dpkg/) pode ser corrompido, no pior caso tornando o gerenciamento de pacotes irrecuperável. Não faça rm até lsof e ps confirmarem que nada está executando.
Como recupero um dpkg interrompido?
Conclusão: Após liberar o lock, execute
sudo dpkg --configure -a. Ele termina de configurar pacotes deixados "descompactados mas não configurados", depoisapt-get install -f/apt updaterestaura a consistência.
Mesmo após o lock ser liberado, um apt anterior que morreu no meio da operação pode deixar pacotes semi-instalados. dpkg --configure -a normaliza isso.
$ sudo dpkg --configure -a
Isso reconfigura todos os pacotes que foram descompactados mas ainda não configurados. Depois repare dependências quebradas e atualize as listas.
$ sudo apt-get install -f $ sudo apt update
apt-get install -f (--fix-broken) repara pacotes com dependências quebradas. Quando isso passar, apt install funciona normalmente de novo.
A sequência padrão de recuperação são estes três, na ordem:
sudo dpkg --configure -a sudo apt-get install -f sudo apt update
Como evitar recorrência?
Conclusão: Em scripts e automação, defina
DPkg::Lock::Timeoutpara que o apt espere pelo lock em vez de falhar instantaneamente. Ele tenta novamente pelo número de segundos dado. Padrão no apt 2.x e posterior.
Para trabalho manual, "esperar a atualização automática terminar" é suficiente. Mas em CI ou scripts de provisionamento, colidir com uma atualização automática e falhar é doloroso. O apt 2.x pode esperar um número 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 automação que executa apt install logo após a inicialização de um servidor, adicionar DPkg::Lock::Timeout sozinho previne a maioria das colisões de lock com o apt-daily da inicialização.
O que não fazer
rmnos arquivos de lock sem verificar se há um processokill -9em um apt / dpkg que está atualizando- Executar duas instâncias de apt ao mesmo tempo no mesmo servidor
Resumo: checklist
Conclusão: A ordem básica é "identificar -> esperar -> recuperar". Excluir arquivos de lock é último recurso, somente após confirmar que nenhum processo os segura. Siga essa ordem e você corrige sem quebrar o dpkg.
- [ ] Identificou quem segura via PID no erro ou
lsof? - [ ] Se é
unattended-upgrade/apt-daily, esperou alguns minutos? - [ ] Verificou que o "Software Updater" / packagekit gráfico não está executando?
- [ ] Se for matar, evitou
kill -9e usousystemctl stopoukillnormal? - [ ] Confirmou com
lsofepsque nada está executando antes de excluir locks? - [ ] Se interrompido, recuperou com
dpkg --configure -a->apt-get install -f->apt update? - [ ] Definiu
DPkg::Lock::Timeoutna automação?