2012-09-11 12 views
3

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

根据实际mod_perl它听起来像识别操作给我头痛的方式是系统跟踪,perl跟踪或交互式调试器。我收集系统跟踪在FreeBSD的ktrace,但是当我连接到顶部在吊的过程之一,经过进程只能输出被杀害的是:

50904 perl5.8.9 PSIG SIGTERM SIG_DFL 

那是不是对我很有帮助。任何人都可以提出一个更有意义的方法吗?我不是非常先进的Unix管理员,所以你的耐心,如果我听起来很愚蠢是非常赞赏....:o)

+1

我会尝试添加一些信号处理和日志开始。如果可以的话,它肯定会有助于启用mysql日志记录,以便查看在锁定时间戳之前/期间所做的操作 - 这可能会提供一些进一步的见解。你碰巧在使用线程吗?任何你可以发布的日志信息都可能帮助任何潜在的SO用户来帮助你。 对于信号处理总是有posix模块 - http://perldoc.perl.org/POSIX.html#POSIX%3a%3aSigAction – AndrewPK

+1

最好的情况是,如果有人可以识别错误,但否则你必须开始记录你的出路。我对日志进行了后处理,以便每个请求将它们提炼为一行,仅包含具有所需开始和结束状态的主要状态更改的描述。然后,您应该能够找到没有所需结束状态的行,并使用上次记录的状态作为提示,指出应该进行更多日志记录。 – mzedeler

回答

0

Ktracing只给你系统调用,信号I/O和namei处理。并且它非常快速地生成一批数据。因此,找出麻烦点可能并不理想。

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

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

如果看不到标准输出,可以使用例如perl模块或调用FreeBSD的logger(1)程序将调试信息写入日志文件。将其封装到debug()函数中并使用该函数或打印语句可能是最容易的。

编辑:如果你不想要很多磁盘上的日志,写日志信息到一个插座(系统日志::支持与setlogsock()),并另写剧本从插座和转储阅读将调试文本发送到终端,并以接收数据的时间作为前缀。一旦程序挂起,你可以看到它在做什么。

+0

很棒的回答。问题是脚本在锁定一次之前会运行一百万次,所以这将是大量的数据记录,并且我认为会在服务器上增加一些负载。鉴于锁定极其罕见的局限性,您如何建议我跟踪锁定而不会造成过多的服务器负载和大量误报? –

+0

使用套接字将调试信息写入。查看更新的答案。 –

0

如果我理解正确,那么在查询MySQL时,您的Perl进程会挂起,而这本身仍在运行。 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,它是一个WordPress超过30K的职位。

+0

我不认为它是MySQL,因为没有脚本的那部分发生锁定。我最终将服务器移到了使用fastcgi的Ubuntu/Nginx框。我必须重写皮肤脚本,但罕见的锁定似乎仍然发生。我有一个cron脚本,用于检查锁定的进程,然后重新启动FCGI包装器,这是一个非常糟糕的解决方案,但确保该包装盒保持99.99%的运行时间。我尝试一行一行的脚本,但没有跳出。我的同事建议我将整个事情转移到PHP,这说起来容易做起来难。 –

+0

FCGI包装已知很难调整;事实上,我经历过许多突然的锁定。另一方面,Nginx对PSGI非常好。例如,您可以尝试使用PSGI封装您的CGI,例如https://metacpan.org/module/CGI::Emulate::PSGI。 – creaktive

+0

感谢creaktive,我会看看该模块.... –