【发布时间】:2015-12-10 14:53:18
【问题描述】:
我在 RealTime Index 中使用 PHP 并通过禁用 AUTOCOMIT 来执行 bulk inserts ,
例如
// sphinx connection
$sphinxql = mysqli_connect($sphinxql_host.':'.$sphinxql_port,'','');
//do some other time consuming work
//sphinx start transaction
mysqli_begin_transaction($sphinxql);
//do 50k updates or inserts
// Commit transaction
mysqli_commit($sphinxql);
并保持脚本运行一夜,早上我看到
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate
212334 bytes) in
所以当我仔细检查nohup.out 文件时,我注意到了这些行,
PHP Warning: mysqli_query(): MySQL server has gone away in /home/script.php on line 502
Warning: mysqli_query(): MySQL server has gone away in /home/script.php on line 502
这几行之前的内存使用是正常的,但是这几行之后的内存使用开始增加,到了phpmem_limit,给了PHPFatal error,死了。
in script.php , line 502 is
mysqli_query($sphinxql,$update_query_sphinx);
所以我的猜测是,狮身人面像服务器在几个小时/分钟不活动后关闭/死亡。
我已经尝试在 sphinx.conf 中设置
client_timeout = 3600
重新开始搜索
systemctl restart searchd
我仍然面临同样的问题。
那么,当长时间没有活动时,我怎么能不让 sphinx 服务器死在我身上呢?
添加了更多信息 -
我一次从 mysql 获取 50k 块的数据,并执行 while 循环来获取每一行并在 sphinx RT 索引中更新它。像这样
//6mil rows update in mysql, so it takes around 18-20 minutes to complete this then comes this following part.
$subset_count = 50000 ;
$total_count_query = "SELECT COUNT(*) as total_count FROM content WHERE enabled = '1'" ;
$total_count = mysqli_query ($conn,$total_count_query);
$total_count = mysqli_fetch_assoc($total_count);
$total_count = $total_count['total_count'];
$current_count = 0;
while ($current_count <= $total_count){
$get_mysql_data_query = "SELECT record_num, views , comments, votes FROM content WHERE enabled = 1 ORDER BY record_num ASC LIMIT $current_count , $subset_count ";
//sphinx start transaction
mysqli_begin_transaction($sphinxql);
if ($result = mysqli_query($conn, $get_mysql_data_query)) {
/* fetch associative array */
while ($row = mysqli_fetch_assoc($result)) {
//sphinx escape whole array
$escaped_sphinx = mysqli_real_escape_array($sphinxql,$row);
//update data in sphinx index
$update_query_sphinx = "UPDATE $sphinx_index
SET
views = ".$escaped_sphinx['views']." ,
comments = ".$escaped_sphinx['comments']." ,
votes = ".$escaped_sphinx['votes']."
WHERE
id = ".$escaped_sphinx['record_num']." ";
mysqli_query ($sphinxql,$update_query_sphinx);
}
/* free result set */
mysqli_free_result($result);
}
// Commit transaction
mysqli_commit($sphinxql);
$current_count = $current_count + $subset_count ;
}
【问题讨论】:
-
您可以更新/插入更小的块。说1k。或在单个查询中更新/插入(如果可能的话)。
-
@Andrew 我每天有大约 600 万条记录要更新,因此每个周期 1k 条记录非常耗时,所以我正在寻找一些可靠的解决方案,甚至像自定义函数重新连接这样的东西,它将保持连接处于活动状态每个循环。
-
您可以发布查询吗?我有一种感觉,这可能比其他任何事情都更相关。
-
@Andrew 我有另一个 cronjob,我在 mysqli_begin_transaction 之前有一些耗时的工作,所以它在初始 mysqli_begin_transaction 时抛出错误,所以我认为一定有我遗漏的东西。我正在用查询更新问题。
-
也可以看看this。
标签: php mysqli sphinx sphinxql