Pergunta

Isso é estranho e eu não tenho certeza de que o culpado é realmente.

Eu estou fazendo alguns scripts, no FreeBSD (6.2)? que faz uso extensivo do seguinte *** festa *** ism:

do_something <(mysql --skip-column-names -B -e 'select ... from ... where ...;')

... onde "do_something é um utilitário pouco intrincada (em Perl) que não vai ler a partir de um pipeline. Se eu usar um arquivo regular funciona bem. Meu o bash script usando coisas como exec 4< <(...) com esses tipos de consultas (seguir por laços do while read x y z <&4; do ... forma nunca parecem ter quaisquer problemas.

No entanto, Perl (5.8.x) parece bloquear periodicamente (aparentemente para sempre). Tentei mudar o chomp(my $data = <MYDATA>); com uma rotina que usou sysread e eu escrevi alguns casos de teste em Python para comparação. Estes parecem bloquear muito menos frequentemente do que o código Perl idiomática, mas eles ainda fazê-lo algumas vezes. (O código Python usando f.read() ou os.read(f.fileno()...) parece comportar-se quase igualmente nesta edição).

Eu tentei reproduzir o problema usando ... <(cat ...) (onde eu sou cat ing o arquivo regular) e que nunca parece reproduzir esse stall.

Eu olhei para alguns ktrace / kdump de dados ... mas eu sou muito mais familiarizado com Linux strace ou mesmo Solaris treliça ... então eu ainda não descobri o que está acontecendo de lá ainda, qualquer um.

Acho que podemos principalmente descarta Perl, porque eu já reproduziu o mesmo problema usando Python ... Eu não vejo como o o bash poderia estar fazendo nada de errado aqui (é apenas criar um pipe nomeado em / var / tmp / sh-np-xxx e fiação dos processos até que).

O que poderia o mysql shell / utilitário de estar fazendo isso pode causar isso? Eu não acho que eu já vi isso de qualquer outra coisa (como cat ou dd ). Eu não testei este cenário no Linux ... mas eu tenho <(...) usado (substituição processo) durante anos sob o Linux e não lembro de ter visto isso.

É uma questão FreeBSD?

Claro que pode contornar o problema usando arquivos temporários ... mas eu tinha certeza que sim entender por que ele está fazendo isso (e evitar algumas das corridas e messiness clean-up que arquivos temporários implicam).

Todas as sugestões?

Foi útil?

Solução

A grande diferença entre a operar na saída do mysql e diretamente em um arquivo é timing. Quando o processo perl está parado, a grande questão é: "por que não é fazer avançar o progresso"? Você pode usar a opção "l" para ps para ver o canal de espera para o processo perl; de que maneira você pode ver se bloqueado em uma leitura, ou se alguma coisa está acontecendo. Se ele é realmente bloqueado na entrada da tubulação, espero que a entrada MWCHAN para perl ser "piperd".

A mesma informação seria interessante para o processo mysql.

O que seu código de teste Python se parece?

Outra forma de escrever este evitando a Bashismo é esta; que lhe permitiria descartar bash:

mysql --skip-column-names -B -e 'select ... from ... where ...;' | do_something /dev/stdin

Outras questões interessantes:

  • Será que a opção --unbuffered à mudança mysql alguma coisa?

  • O canalizando a saída mysql através dd mudar alguma coisa? (Por exemplo, "PerlScript <(mysql ... |. Dd)

Resumo:. Precisa de mais informações

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top