检测Perl / MySQL中的挂起进程(FreeBSD)

时间:2012-09-11 23:22:43

标签: mysql perl apache freebsd dbi

我有一个在FreeBSD / Apache系统上运行的Perl脚本,它通过DBI对MySQL数据库进行一些简单的查询。服务器相当活跃(每天150k页),每隔一段时间(每分钟一次)就会导致进程挂起。我怀疑文件锁可能会阻止读取,或者可能是SQL调用,但我无法弄清楚如何获取有关挂起过程的信息。

Per Practical mod_perl听起来像识别操作让我头痛的方法是系统跟踪,perl跟踪或交互式调试器。我在FreeBSD上收集系统跟踪是ktrace,但是当我附加到top中的一个挂起进程时,进程被杀死后的唯一输出是:

50904 perl5.8.9 PSIG  SIGTERM SIG_DFL

这对我没有多大帮助。任何人都可以建议一个更有意义的方法吗?我在Unix管理员方面并不是非常先进,所以如果我听起来很愚蠢你的耐心是非常感谢....:o)

2 个答案:

答案 0 :(得分:0)

Ktracing只为您提供系统调用,信号I / O和名称处理。它可以非常快速地生成 lot 数据。因此,找出麻烦点可能并不理想。

如果您可以看到脚本的标准输出,请在代码中放置一些策略性的打印语句,围绕可疑的问题点。然后运行该程序应该会显示发生了挂起:

print "Before query X"
$dbh->do($statement)
print "After query X".

如果您看不到标准输出,请使用例如Sys::Syslog perl模块,或调用FreeBSD的logger(1)程序将调试信息写入日志文件。将它封装到debug()函数中并使用它代替或打印语句可能是最简单的。

编辑:如果您不想在磁盘上进行大量日志记录,请将日志记录信息写入套接字(Sys :: Syslog支持使用setlogsock()),然后编写另一个脚本从该套接字读取并将调试文本转储到终端,前缀为接收数据的时间。一旦程序挂起,你就可以看到它正在做什么。

答案 1 :(得分:0)

如果我理解正确,你的Perl进程在查询MySQL时就会挂起,而MySQL本身仍在运行。 MySQL服务器具有log_slow_queries选项的嵌入式故障排除功能。在my.cnf中添加以下行可以实现诀窍:

[mysqld]
log_slow_queries = /var/log/mysql/mysql-slow.log
long_query_time = 10

之后,重新启动或重新加载MySQL守护程序。让服务器运行一段时间来收集统计数据并分析发生了什么:

mysqldumpslow -s at /var/log/mysql/mysql-slow.log | less

在我的一台服务器上,最高记录(-s at订单的平均查询时间,BTW)是:

Count: 286  Time=101.26s (28960s)  Lock=14.74s (4214s)  Rows=0.0 (0), iwatcher[iwatcher]@localhost
  INSERT INTO `wp_posts` (`post_author`,`post_date`,`post_date_gmt`,`post_content`,`post_content_filtered`,`post_title`,`post_excerpt`,`post_status`,`post_type`,`comment_status`,`ping_status`,`post_password`,`post_name`,`to_ping`,`pinged`,`post_modified`,`post_modified_gmt`,`post_parent`,`menu_order`,`guid`) VALUES ('S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S')

FWIW,它是一个拥有超过30K帖子的WordPress。