Como resolver o erro “Muitos arquivos abertos” no Linux

Laptop Linux mostrando um prompt do bash

Em computadores Linux, os recursos do sistema são compartilhados entre os usuários. Tente usar mais do que o seu quinhão e você atingirá um limite superior. Você também pode causar gargalos em outros usuários ou processos.

Qual é o erro de muitos arquivos abertos?

Entre seus zilhões de tarefas, o kernel de um computador Linux está sempre ocupado observando quem está usando quantos recursos finitos do sistema, como RAM e ciclos de CPU . Um sistema multiusuário requer atenção constante para garantir que pessoas e processos não estejam usando mais recursos do sistema do que o apropriado.

Não é justo, por exemplo, que alguém gaste tanto tempo de CPU que o computador pareça lento para todos os outros. Mesmo que você seja a única pessoa que usa seu computador Linux, existem limites definidos para os recursos que seus processos podem usar. Afinal, você ainda é apenas mais um usuário.

Alguns recursos do sistema são bem conhecidos e óbvios, como RAM, ciclos de CPU e espaço no disco rígido. Mas há muitos, muitos mais recursos que são monitorados e para os quais cada usuário — ou cada processo de propriedade do usuário — tem um limite superior definido. Um deles é o número de arquivos que um processo pode abrir ao mesmo tempo.

Se você já viu a mensagem de erro “Muitos arquivos abertos” em uma janela de terminal ou a encontrou nos logs do sistema, significa que o limite superior foi atingido e o processo não tem permissão para abrir mais arquivos.

Por que tantos arquivos estão abrindo?

Há um limite em todo o sistema para o número de arquivos abertos que o Linux pode manipular. É um número muito grande, como veremos, mas ainda há um limite. Cada processo do usuário possui uma alocação que pode usar. Cada um deles recebe uma pequena parcela do total do sistema alocado a eles.

O que realmente é alocado são vários identificadores de arquivo. Cada arquivo aberto requer um identificador. Mesmo com alocações bastante generosas, os identificadores de arquivos em todo o sistema podem se esgotar mais rapidamente do que você imagina.

O Linux abstrai quase tudo para que pareça um arquivo . Às vezes, eles serão apenas isso, simples arquivos antigos. Mas outras ações, como abrir um diretório, também usam um identificador de arquivo. O Linux usa arquivos especiais de bloco como uma espécie de driver para dispositivos de hardware. Arquivos especiais de caracteres são muito semelhantes, mas são usados ​​com mais frequência com dispositivos que possuem um conceito de taxa de transferência, como pipes e portas seriais.

Recomendado:  Qual alto-falante inteligente tem a melhor qualidade de áudio?

Arquivos especiais de bloco lidam com blocos de dados por vez e arquivos especiais de caracteres lidam com cada caractere separadamente. Ambos os arquivos especiais só podem ser acessados ​​usando identificadores de arquivo. As bibliotecas usadas por um programa usam um identificador de arquivo, os fluxos usam identificadores de arquivo e as conexões de rede usam identificadores de arquivo.

Abstrair todos esses diferentes requisitos para que apareçam como arquivos simplifica a interface com eles e permite que coisas como tubulações e fluxos funcionem.

Você pode ver que nos bastidores o Linux está abrindo arquivos e usando identificadores de arquivos apenas para executar a si mesmo – não importa os processos do usuário . A contagem de arquivos abertos não é apenas o número de arquivos que você abriu. Quase tudo no sistema operacional usa identificadores de arquivo.

Como verificar os limites de manipulação de arquivos

O número máximo de identificadores de arquivo em todo o sistema pode ser visto com este comando.

gato /proc/sys/fs/file-max

Encontrando o máximo do sistema para arquivos abertos

Isso retorna um número absurdamente grande de 9,2 quintilhões. Esse é o máximo teórico do sistema. É o maior valor possível que você pode manter em um número inteiro assinado de 64 bits . Se o seu pobre computador conseguiria realmente lidar com tantos arquivos abertos ao mesmo tempo é outra questão.

No nível do usuário, não há um valor explícito para o número máximo de arquivos abertos que você pode ter. Mas podemos resolver isso aproximadamente. Para saber a quantidade máxima de arquivos que um de seus processos pode abrir, podemos utilizar o ulimitcomando com a -nopção (abrir arquivos).

ulimit -n

Descobrir quantos arquivos um processo pode abrir

E para encontrar o número máximo de processos que um usuário pode ter usaremos ulimita -uopção (processos do usuário).

ulimit -u

Encontrar o número de processos que um usuário pode ter

Multiplicar 1.024 por 7.640 nos dá 7.823.360. É claro que muitos desses processos já serão usados ​​pelo seu ambiente de trabalho e outros processos em segundo plano. Portanto, esse é outro máximo teórico e que você nunca alcançará de forma realista.

Recomendado:  Como baixar seus jogos salvos do Steam Cloud

O número importante é o número de arquivos que um processo pode abrir. Por padrão, é 1.024. É importante notar que abrir o mesmo arquivo 1.024 vezes simultaneamente é o mesmo que abrir 1.024 arquivos diferentes simultaneamente. Depois de usar todos os identificadores de arquivo, pronto.

É possível ajustar o número de arquivos que um processo pode abrir. Na verdade, existem dois valores a serem considerados ao ajustar esse número. Um é o valor com o qual está definido atualmente ou com o qual você está tentando defini-lo. Isso é chamado de limite suave. Também existe um limite rígido e este é o valor mais alto para o qual você pode aumentar o limite flexível.

A maneira de pensar sobre isso é que o limite flexível é realmente o “valor atual” e o limite superior é o valor mais alto que o valor atual pode atingir. Um usuário normal, não root, pode aumentar seu limite flexível para qualquer valor até seu limite rígido. O usuário root pode aumentar seu limite rígido.

Para ver os limites flexíveis e rígidos atuais, use ulimitas opções -S(soft) e -H(hard) e a -nopção (abrir arquivos).

ulimit -Sn

ulimit -Hn

Encontrando o limite flexível e rígido para identificadores de arquivos de processo

Para criar uma situação em que possamos ver o limite flexível sendo aplicado, criamos um programa que abre arquivos repetidamente até falhar. Em seguida, ele aguarda um pressionamento de tecla antes de abandonar todos os identificadores de arquivo usados. O programa é chamado open-files.

./Abrir arquivos

O programa de arquivos abertos atingindo o limite flexível de 1024

Ele abre 1.021 arquivos e falha ao tentar abrir o arquivo 1.022.

1.024 menos 1.021 é 3. O que aconteceu com os outros três identificadores de arquivo? Eles foram usados ​​para , , e streamsSTDINSTDOUTSTDERR . Eles são criados automaticamente para cada processo. Eles sempre têm valores de descritor de arquivo 0, 1 e 2.

Podemos ver isso usando o lsofcomando com a -popção (processo) e o ID do processo do open-filesprograma. Facilmente, ele imprime seu ID de processo na janela do terminal.

lsof -p 11038

Os fluxos stdin, stdout e stderr e identificadores de arquivo na saída do comando lsof

Claro, em uma situação do mundo real, você pode não saber qual processo acabou de engolir todos os identificadores de arquivo. Para iniciar sua investigação, você pode usar esta sequência de comandos canalizados. Ele mostrará os quinze usuários mais prolíficos de identificadores de arquivos em seu computador.

lsof | awk '{imprime $1 " " $2; }' | classificar -rn | único -c | classificar -rn | cabeça -15

Vendo os processos que usam mais identificadores de arquivo

Para ver mais ou menos entradas ajuste o -15parâmetro ao headcomando. Depois de identificar o processo, você precisa descobrir se ele se tornou desonesto e está abrindo muitos arquivos porque está fora de controle ou se realmente precisa desses arquivos. Se precisar deles, você precisará aumentar o limite de manipulação de arquivos.

Como aumentar o limite suave

Se aumentarmos o limite flexível e executarmos nosso programa novamente, veremos que ele abre mais arquivos. Usaremos o ulimitcomando e a -nopção (abrir arquivos) com valor numérico de 2048. Este será o novo limite flexível.

Recomendado:  Este novo telefone Nokia de US $ 239 tem 5G e uma tela de 120Hz

ulimit -n 2048

Configurando um novo limite flexível de manipulação de arquivo para processos

Desta vez, abrimos com sucesso 2.045 arquivos. Como esperado, isso é três a menos que 2.048, devido aos identificadores de arquivo usados ​​para STDIN, STDOUTe STDERR.

Como alterar permanentemente o limite de arquivos

Aumentar o limite flexível afeta apenas o shell atual. Abra uma nova janela de terminal e verifique o limite flexível. Você verá que é o antigo valor padrão. Mas existe uma maneira de definir globalmente um novo valor padrão para o número máximo de arquivos abertos que um processo pode ter, que seja persistente e sobreviva às reinicializações .

Conselhos desatualizados geralmente recomendam que você edite arquivos como “/etc/sysctl.conf” e “/etc/security/limits.conf”. No entanto, em distribuições baseadas no systemd , essas edições não funcionam de forma consistente, especialmente para sessões de login gráfico.

A técnica mostrada aqui é a maneira de fazer isso em distribuições baseadas em systemd. Existem dois arquivos com os quais precisamos trabalhar. O primeiro é o arquivo “/etc/systemd/system.conf”. Precisaremos usar sudo.

sudo gedit /etc/systemd/system.conf

Editando o arquivo system.conf

Procure a linha que contém a string “DefaultLimitNOFILE”. Remova o hash “#” do início da linha e edite o primeiro número para o que você deseja que seja o novo limite flexível para os processos. Escolhemos 4096. O segundo número nessa linha é o limite rígido. Não ajustamos isso.

O valor DefaultLimitNOFILE no arquivo system.conf

Salve o arquivo e feche o editor.

Precisamos repetir essa operação no arquivo “/etc/systemd/user.conf”.

sudo gedit /etc/systemd/user.conf

Editando o arquivo user.conf

Faça os mesmos ajustes na linha que contém a string “DefaultLimitNOFILE”.

O valor DefaultLimitNOFILE no arquivo user.conf

Salve o arquivo e feche o editor. Você deve reiniciar o computador ou usar o systemctlcomando com a daemon-reexecopção para que systemdseja executado novamente e ingira as novas configurações.

sudo systemctl daemon-reexec

Reiniciando o sistema

Abrir uma janela de terminal e verificar o novo limite deverá mostrar o novo valor que você definiu. No nosso caso, foi 4096.

ulimit -n

Verificando o novo limite flexível com ulimit -n

Podemos testar se este é um valor operacional e ativo executando novamente nosso programa ávido por arquivos.

./Abrir arquivos

Verificando o novo limite flexível com o programa de arquivos abertos

O programa não consegue abrir o arquivo número 4094, o que significa que 4093 foram arquivos abertos. Esse é o nosso valor esperado, 3 a menos que 4.096.

Lembre-se de que tudo é um arquivo

É por isso que o Linux é tão dependente de identificadores de arquivos. Agora, se começar a ficar sem eles, você sabe como aumentar sua cota.