很長時間沒有更新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。