Estou enfrentando uma lentidão extrema ao abrir subshells (usando substituições de comando ` ` ou $( ) em scripts) enquanto estou em ksh
alguns servidores Linux. O mesmo problema não existe em sh
ou qualquer outro shell. strace
indica que o tempo é devido stat
e openat
chama contra arquivos nomeados aleatoriamente em /tmp.
teste.sh :
echo `expr 1 + 1`
comando :
strace -tttT ksh test.sh
saída :
. . .[snipped]. . .
1734368858.571604 stat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=708608, ...}) = 0 <0.613038>
1734368859.184765 geteuid() = 1001 <0.000011>
1734368859.184851 getegid() = 1002 <0.000008>
1734368859.184879 getuid() = 1001 <0.000013>
1734368859.184913 getgid() = 1002 <0.000007>
1734368859.184946 access("/tmp", W_OK|X_OK) = 0 <0.000020>
1734368859.185012 getpid() = 210594 <0.000009>
1734368859.185055 openat(AT_FDCWD, "/tmp/sf0p.si0", O_RDWR|O_CREAT|O_EXCL, 0666) = 1 <1.586349>
1734368860.771539 unlink("/tmp/sf0p.si0") = 0 <0.008521>
. . .
Entre stat
e openat
, minha simples invocação de expr 1 + 1
levou mais de 2 segundos.
Questões:
- Por que o ksh está criando arquivos no
/tmp
, enquanto nenhum outro shell (sh, bash, csh) faz isso? - Como posso começar a diagnosticar por que essas operações levariam de 1 a 2 segundos?
O servidor em questão está na versão: Linux 5.4.17-2136.322.6.4.el8uek.x86_64
(distribuição Oracle Linux Server release 8.9
). Ksh é a versãoAJM 93u+ 2012-08-01
Atualizar:
Vimos alguns artefatos do python criando diretórios vazios em /tmp, que alguns dias atrás eu descobri que somavam 10.000 subdiretórios em /tmp. Eu os apaguei todos, mas isso não ajudou no desempenho. Perdoe minha falta de conhecimento de Unix, mas estou certo em assumir que, uma vez que o inode do diretório é ampliado para listar um número tão extenso de subdiretórios/arquivos, a exclusão deles não encolhe o inode do diretório em si, mas deixa uma estrutura esparsa que ainda precisa ser escaneada por todos os acessos de arquivo? O tamanho do inode do meu /tmp ( ls -ld /tmp
) é atualmente 708 KB. Isso é 172x maior do que o tamanho inicial de 4096 bytes. Poderia ser isso que está deixando lento stat
e openat
as chamadas que atingem /tmp
?
ksh93
irá gerar arquivos temporários se a execução do comando for um comando externo . Então, por exemplonão irá gerar um arquivo temporário, mas
faz.
por exemplo
O interessante é que isso segue
$TMPDIR
as configurações de ambiente padrão (vejaman 3 tempnam
).por exemplo
Isso pode permitir que você mova esses arquivos temporários para locais mais rápidos (por exemplo, tmpfs, talvez
/run
?) ou áreas com menos contenção de disco em um ambiente movimentado.Ao executar um comando externo (por exemplo, /bin/echo neste exemplo), o ksh criará este arquivo temporário, definirá o stdout do comando para o filehandle e excluirá o arquivo. A saída do comando é enviada para este arquivo excluído e, em seguida, é lida para obter os resultados. Quando o comando for concluído e os dados lidos no arquivo excluído forem limpos. Presumo que seja uma tentativa de economizar memória.
Outros shells podem se comportar de forma diferente porque são bases de código diferentes.