很长时间没有更新drupal 网站的sitemap了,近期用drush xmlsitemap-regenerate命令来批量更新,但在遇到数据量大的网站时,有时会遇到类似这样的报错:
Fatal error: Maximum execution time of 240 seconds exceeded in /mnt/gb2/htdocs/drupal.mingluji.com/includes/path.inc on line 115 Drush command terminated abnormally due to an unrecoverable error. [error]
有时是includes/path.inc报错,有时是includes/common.inc,sites/all/modules/xmlsitemap/xmlsitemap.module等,网上查了一些资料,试着改了php.ini、.htaccess、common.inc、mysql.inc、locale.inc、modules/node/node.module等程序中的时间限制设置,到都没有效果,最后修改sites/all/modules/xmlsitemap/xmlsitemap.module中的这个才解决:
// Attempt to increase the execution time. //jamesqi2013-1-10 xmlsitemap_set_time_limit(240); xmlsitemap_set_time_limit(1800);
这里把240秒的限制改成了1800秒。(补充:改为1800秒后基本上都可以解决,但有一些多语言网站,在生成多达50种语言的站点地图时依然会报告1800秒超时,干脆改为24000秒,就都不会再报超时错了。)
补充:drupal 7中可能改为如下:
// Attempt to increase the execution time. //jamesqi2013-4-12 drupal_set_time_limit(240); drupal_set_time_limit(1800);
另外,如果发现'Unknown error occurred while writing to file sites'、'XMLSitemapGenerationException'这样的报错,可以修改xmlsitemap.xmlsitemap.inc的第161行,把
if (!$this->getStatus()) {
改为
//jamesqi 2013-4-12 if (!$this->getStatus()) { if (!$return) {
就可以了。
2013-12-20补充:
如果在运行drush xmlsitemap-rebuild时遇到PHP内存不足的报错,可以修改/etc/php.ini,将memory_limit = 4096M改为更多,例如memory_limit = 28672M,然后用service httpd restart重启Apache,再次运行drush xmlsitemap-rebuild看看。
还有遇到网站数据量极大的情况,修改PHP内存都要超过实际内存,那就不要用drush xmlsitemap-rebuild命令,可以先运行drush cron名录很多次,让xmlsitemap表符合实际node、term、menu等的数量,最后运行一次drush xmlsitemap-regenerate就可以。
一般运行drush xmlsitemap-regenerate速度比较快、占用内存也少,如果有遇到运行很长时间还在等待的情况,可以检查xmlsitemap设置中的“Prefetch URL aliases during sitemap generation.”,如果未选则改为勾选。
如果在运行drush xmlsitemap-rebuild时遇到General error: 2013 Lost connection to MySQL server,有可能是我们的checkmysql.sh自动kill了超时的MySQL进程,这时可以临时调高checkmysql.sh超时的限制,生成网站地图后再恢复。
2016年2月25日补充:114.mingluji.com有400多万数据,运行drush xmlsitemap-rebuild老是中断,PHP Fatal error: Allowed memory size of 10737418240 bytes exhausted,可以编写一个shell循环来执行drush xmlsitemap-index很多次来进行索引,然后再drush xmlsitemap-regenerate生成文件:
for (( i=1; i<=4000; i++ )) do echo "$i of 4000 times" drush xmlsitemap-index done
2016年3月24日补充:对于数百万页面的站点,regenerate生成sitemap过程中可能导致数据库服务器的IOPS大幅度上升、连接堆积,查看sql语句是这样的:
SELECT x.id AS id, x.type AS type, x.subtype AS subtype, x.loc AS loc, x.lastmod AS lastmod, x.changefreq AS changefreq, x.changecount AS changecount, x.priority AS priority, x.language AS language, x.access AS access, x.status AS status FROM xmlsitemap x WHERE (x.access = '1') AND (x.status = '1') ORDER BY x.language DESC, x.loc ASC LIMIT 1000 OFFSET 103000
在mysql进程列表中显示Creating sort index,这应该是因为有排序操作而写大量临时文件到磁盘造成IO过高,而这个排序对我们来说并不算很重要,可以修改xmlsitemap.generate.inc中的语句去掉排序:
$query = db_select('xmlsitemap', 'x'); $query->fields('x', array('id', 'type', 'subtype', 'loc', 'lastmod', 'changefreq', 'changecount', 'priority', 'language', 'access', 'status')); $query->condition('x.access', 1); $query->condition('x.status', 1); //jamesqi 2-16-3-24// $query->orderBy('x.language', 'DESC'); // $query->orderBy('x.loc'); $query->addTag('xmlsitemap_generate'); $query->addMetaData('sitemap', $sitemap);
这样查询语句就变成了:
SELECT x.id AS id, x.type AS type, x.subtype AS subtype, x.loc AS loc, x.lastmod AS lastmod, x.changefreq AS changefreq, x.changecount AS changecount, x.priority AS priority, x.language AS language, x.access AS access, x.status AS status FROM xmlsitemap x WHERE (x.access = '1') AND (x.status = '1') LIMIT 1000 OFFSET 810000
再运行生成网站地图就没有出现数据库服务器IO堵塞的情况。
评论1
数据量很大的时候,一定要慎用drush
数据量很大的时候,一定要慎用drush xmlsitemap-rebuild!! 遇到有内容类型的数量没有正确VISIBLE数量的时候,可以先运行drush xmlsitemap-queue-rebuild,在循环运行drush xmlsitemap-index。页面数量正确以后,最后再运行一次drush xmlsitemap-regenerate。