FreeBSD,MySQL,Perl,bash:命名管道上的间歇性阻塞?

时间:2009-10-31 04:57:47

标签: mysql perl bash named-pipes freebsd

这很奇怪,我不确定罪魁祸首是谁。

我在FreeBSD(6.2)上做一些脚本编写?这大量使用以下*** bash *** ism:

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

...其中“do_something是一个有点狡猾的实用程序(在Perl中),不会从管道读取。如果我使用常规文件,它工作正常。我的 bash 脚本使用像exec 4< <(...)使用这些类型的查询(跟随while read x y z <&4; do ...形式的循环后似乎没有任何问题。

然而,Perl(5.8.x)似乎会定期阻止(显然是永远)。我尝试使用 sysread 的例程更改chomp(my $data = <MYDATA>);,并在Python中编写了一些测试用例以进行比较。这些似乎比惯用的Perl代码阻止的频率低得多,但它们有时仍会这样做。 (使用f.read()os.read(f.fileno()...)的Python代码似乎在此问题中的行为相同。)

我尝试使用... <(cat ...)(我在 cat 中查找常规文件)来重现此问题,并且似乎永远不会重现该停顿。

我已经看了一些 ktrace / kdump 数据...但我对Linux strace 甚至Solaris truss ...所以我还没弄清楚那里发生了什么。

我想我们可以主要排除Perl,因为我使用Python重现了同样的问题...我不知道 bash 在这里做错了什么(它只是创建 / var / tmp / sh-np-xxx 中的命名管道,并将流程连接到该管道。

mysql shell /实用程序可能会导致什么?我认为我没有看到任何其他内容(例如 cat dd )。我没有在Linux下测试过这个场景......但是我已经在Linux下使用了<(...)(进程替换)多年了,并且不记得曾经看过这个。

这是一个FreeBSD问题吗?

当然,我可以使用临时文件来解决这个问题...但我肯定会理解为什么会这样做(并避免临时文件所带来的一些比赛和清理混乱)。

有什么建议吗?

1 个答案:

答案 0 :(得分:4)

操作mysql的输出和直接在文件上的最大区别是时间。当perl进程停滞不前时,最大的问题是:“为什么它没有取得进展”?您可以使用ps的“l”选项来查看perl进程的等待通道;通过这种方式,您可以查看它是否在读取时被阻止,或者是否正在进行其他操作。如果它确实在管道输入上被阻止,我希望perl的MWCHAN条目是“piperd”。

对于mysql进程,相同的信息会很有趣。

您的Python测试代码是什么样的?

另一种在避免讽刺的同时写这个的方法是这样的;这将允许你排除bash:

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

其他有趣的问题:

  • mysql的--unbuffered选项是否会改变任何内容?

  • 通过dd管道mysql输出会改变什么吗? (例如,“perlscript&lt;(mysql ... | dd)

摘要:需要更多信息。