该计划工作正常,但需要很长时间.所以我决定分叉主解析过程.
在用叉子进行一些争吵后,它现在运行良好,运行速度提高了约4倍.主要的解析方法是数据库密集型的.为了兴趣,对于每个被解析的记录,有以下db调用:
1 – 检查唯一生成的base62对于baseid映射表是唯一的
2 – 存档检查以查看记录是否已更改
3 – 将记录插入数据库
问题是,当解析器以分叉模式运行时,我开始得到“MysqL已经消失”的错误,所以经过多次摆弄后我想出了以下mysql配置:
# # * Fine Tuning # key_buffer = 10000M max_allowed_packet = 10000M thread_stack = 192K thread_cache_size = 8 myisam-recover = BACKUP max_connections = 10000 table_cache = 64 thread_concurrency = 32 wait_timeout = 15 tmp_table_size = 1024M query_cache_limit = 2M #query_cache_size = 100M query_cache_size = 0 query_cache_type = 0
解析器运行时似乎已经解决了问题但是,当主解析器运行下一个模块时,我现在得到一个“MysqL服务器已经消失”.
奇怪的thinf是导致问题的模块涉及一个非常简单的SELECT查询,当前只有3条记录.直接作为测试运行(不是在解析器之后)它运行正常.
我尝试在解析器模块运行后添加4分钟的暂停 – 但是我得到了同样的错误.
我有一个主DBConnection.pm模型:
包DBConnection;
use DBI; use PXConfig; sub new { my $class = shift; ## MysqL Connection my $config = new PXConfig(); my $host = $config->val('database','host'); my $database = $config->val('database','db'); my $user = $config->val('database','user'); my $pw = $config->val('database','password'); my $dsn = "DBI:MysqL:database=$database;host=$host;"; my $connect2 = DBI->connect( $dsn,$user,$pw,); $connect2->{MysqL_auto_reconnect} = 1; $connect2->{RaiseError} = 1; $connect2->{PrintError} = 1; $connect2->{ShowErrorStatement} = 1; $connect2->{InactiveDestroy} = 1; my $self = { connect => $connect2,}; bless $self,$class; return $self; }
然后,所有模块(包括分叉的解析器模块)使用以下命令打开与DB的连接:
package Example; use DBConnection; sub new { my $class = shift; my $db = new DBConnection; my $connect2 = $db->connect(); my $self = { connect2 => $connect2,$class; return $self; }
问题是我是否有调用Module3.pm的Module1.pm,它调用Module3.pm并且每个都实例化与DB的连接,如上所示(即在构造函数中)然后他们使用不同的连接到数据库或相同连接?
我想知道的是,如果脚本需要6个小时才能完成,如果对数据库连接的最高级别调用是超时低级别数据库连接,即使较低级别模块正在建立其“自己的”连接.
尝试找到问题非常令人沮丧,因为我只能在运行一个非常长的解析过程后重现错误.
很抱歉这个问题很长,感谢任何可以给我任何想法的人.
更新1:
这是实际的分叉部分:
my $fh = Tie::Handle::CSV->new( "$file",header => 1 ); while ( my $part = <$fh> ) { if ( $children == $max_threads ) { $pid = wait(); $children--; } if ( defined( $pid = fork ) ) { if ($pid) { $children++; } else { $cfptu = new ThreadedUnit(); $cfptu->parseThreadedUnit($part,$group_id,$Feed_id); } } }
然后是ThreadedUnit:
package ThreadedUnit; use CollisionChecker; use ArchiveController; use Filters; use Try::Tiny; use MysqLLogger; sub new { my $class = shift; my $db = new DBConnection; my $connect2 = $db->connect(); my $self = { connect2 => $connect2,$class; return $self; } sub parseThreadedUnit { my ( $self,$part,$Feed_id ) = @_; my $connect2 = $self->{connect2}; ## Parsing stuff ## DB Update in try -> catch exit(); }
但是,正如我上面提到的,上面概述的分叉代码工作正常.它是下一个无法运行的模块,它从一个控制器模块运行,该控制器模块一次只运行一个工作模块(解析器就是其中之一) – 控制器模块不在其构造中或任何地方创建数据库连接其他.
更新2
我忘了提到我在解析器后面的’problem’模块中没有出现任何错误,如果我只解析少量文件而不是完整队列.
因此,几乎就像密集分叉解析和访问数据库一样,它在正常的非分叉进程刚刚结束一段时间后就不可用了.
当解析器运行完成MysqL状态时,我唯一注意到的是Threads_connected位于500周围并且不会减少一段时间.