3

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

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

50904 perl5.8.9 PSIG  SIGTERM SIG_DFL

这对我不是很有帮助。任何人都可以提出更有意义的方法吗?我在 Unix 管理员方面并不是非常先进,所以如果我听起来很愚蠢,您的耐心将不胜感激...... :o)

4

2 回答 2

0

Ktracing 只为您提供系统调用、信号 I/O 和 namei 处理。而且它会非常快速地生成大量数据。因此,找出麻烦点可能并不理想。

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

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

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

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

于 2012-12-23T19:29:40.757 回答
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按平均查询时间排序,顺便说一句)是:

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。

于 2012-12-23T20:13:26.663 回答