MySQL一直处于挂起状态(查询停留在发送数据上)


10

我有以下情况:

每周大约5次(与缓存清除,流量高峰等任何特定情况无关),某些查询停留在发送数据(show processlist)上:

>     SELECT `main_table`.`entity_id`, `main_table`.`level`, `main_table`.`path`, `main_table`.`position`,
> `main_table`.`is_active`, `main_table`.`is_anchor`,
> `main_table`.`name`, `url_rewrite`.`request_path` FROM
> `catalog_category_flat_store_30` AS `main_table`
>      LEFT JOIN `core_url_rewrite` AS `url_rewrite` ON url_rewrite.category_id=main_table.entity_id AND
> url_rewrite.is_system=1 AND url_rewrite.product_id IS NULL AND
> url_rewrite.store_id='30' AND url_rewrite.id_path LIKE 'category/%'
> WHERE (path LIKE '1/2/%') AND (main_table.store_id = '30') AND
> (is_active = '1') AND (include_in_menu = '1') ORDER BY name ASC

第二个:

> SELECT `main_table`.`entity_id`, main_table.`name`, main_table.`path`,
> `main_table`.`is_active`, `main_table`.`is_anchor`,
> `main_table`.`manually`, `url_rewrite`.`request_path` FROM
> `catalog_category_flat_store_10` AS `main_table`  LEFT JOIN
> `core_url_rewrite` AS `url_rewrite` ON
> url_rewrite.category_id=main_table.entity_id AND
> url_rewrite.is_system=1 AND url_rewrite.product_id IS NULL AND
> url_rewrite.store_id='10' AND url_rewrite.id_path LIKE 'category/%'
> WHERE (main_table.is_active = '1') AND (main_table.include_in_menu =
> '1') AND (main_table.path like '1/2/1528/1569/%') AND (`level` <= 4)
> ORDER BY `main_table`.`position` ASC

这些查询与生成导航菜单有关。它们运行时没有任何问题,而且一直非常快。

一个月很少有几次其他查询卡在seding数据或等待表锁定上:

INSERT INTO `catalogsearch_result` SELECT 316598 AS `query_id`, `s`.`product_id`, MATCH (s.data_index) AGAINST ('STRING HERE' IN BOOLEAN MODE) AS `relevance` FROM `catalogsearch_fulltext` AS `s`
INNER JOIN `catalog_product_entity` AS `e` ON e.entity_id = s.product_id WHERE (s.store_id = 38) AND (MATCH (s.data_index) AGAINST ('STRING HERE' IN BOOLEAN MODE)) ON DUPLICATE KEY UPDATE `relevance` = VALUES(`relevance`)

(与搜索相关)

附加信息:

  • core_url_rewrite-3M条记录(30个网站,10万个产品)
  • catalog_category_flat_store_ *-2000条记录(启用了使用平面类别)

这是在一些大型硬件上使用vmware的安装程序上运行的(mysql主站分配了8个核心,并在SAN存储上分配了64Gb的RAM和SSD磁盘),对mysql进行了优化和连续监控。过去存在一些与I / O相关的问题(服务器和SAN存储之间的链接存在一些问题)。

我们无法确定问题的原因,因为在高压力条件下(运行攻城+负载测试方案,没有缓存),在裸机上运行(无虚拟化,配置相同)永远不会发生。

还有其他人遇到类似的问题吗?

更新:

reindexAll搜索已移动到临时表(因此它不会锁定生产使用的主表,然后重命名tmp表)。因此,重新索引过程不会干扰访问者搜索网站。 https://github.com/magendooro/magento-fulltext-reindex对carco表示感谢


您确定他们跑得快吗?另一种可能是导航菜单被缓存。Afaik使用索引并不容易,因为在category_ud,is_system和path上没有索引。而且路径很像,所以MySQL在这里确实有一个问题。我没有分贝出口顺便说一句;-)只有2美分
Fabian Blechschmidt

1
该选择的运行时间不到1秒。当第一个停留在发送数据时,查询不断堆积……
FlorinelChis

1
FWIW我也看到过同样的问题。
philwinkle

@philwinkle您的搜索设置如何?全文?
FlorinelChis

1
github.com/magendooro/magento-fulltext-reindex这对我们有所帮助,并决定发布源代码。
FlorinelChis

Answers:


4

看起来像是我们在1.7中看到的核心错误/回归,其中块和集合缓存对于导航菜单(catalog/navigation/top.phtml)无效。

您可以通过删除它来进行测试,或者只是使用临时将输出捕获到文件中ob_start并从静态文件/内存缓存中提供它。

而且,您所使用的硬件听起来并不庞大,并且看起来低于您所拥有商店的大小。那里也可能存在I / O瓶颈-SAN存储+网络拥塞=性能不佳。

-

作为粗略的解决方案,您可以调整导航(转储get_class($this))的块类以top.phtml进行识别。

这将允许站点范围的缓存,而无需调用新版本的类别级别的缓存。is_active如果您这样做是为了避免出现随机菜单项被选中的情况,那么还可以从树渲染器中删除该类(并改为实施JS替代方法)。

public function getCacheTags()
{
  return parent::getCacheTags();
}
public function getCacheLifetime()
{
  return null;
}
public function getCacheKey()
{
  return parent::getCacheKey();
}
public function getCacheKeyInfo()
{
  $shortCacheId = array(
    'CATALOG_NAVIGATION',
    Mage::app()->getStore()->getId(),
    Mage::getDesign()->getPackageName(),
    Mage::getDesign()->getTheme('template'),
    Mage::getSingleton('customer/session')->getCustomerGroupId(),
    'template' => $this->getTemplate(),
    'name' => $this->getNameInLayout(),
  );
  $cacheId = $shortCacheId;
  $shortCacheId = array_values($shortCacheId);
  $shortCacheId = implode('|', $shortCacheId);
  $shortCacheId = md5($shortCacheId);
  $cacheId['short_cache_id'] = $shortCacheId;
  return $cacheId;
}

我们以前分配了32核和92Gb的ram(并相应地更改了mysql配置,结果相同)-服务器具有64核和184 gb的ram(这就是为什么我说它很大)的原因...抱歉,我没有提到它是Magento Enterprise 1.12。我们监控了网络流量,没有发现任何瓶颈问题(之前有问题,光纤连接器无法正常工作,已被更换)。
FlorinelChis

企业版1.12是CE 1.7-它们是相同的代码库。因此,该错误会影响他们两个。尝试我所说的(硬编码顶部导航并禁用分层导航上的类别),您可以确认。如果没有正确设置软件来使用它,那么更多的硬件将无济于事。
Ben Lessani-Sonassi

我将编辑我的答案,并添加一些hacky代码供您确认
Ben Lessani-Sonassi 2013年

这是一个不错的起点,我将放置一些东西,看看它是否仍在1周内崩溃:)
FlorinelChis 2013年

3

替换功能

app / code / core / Mage / Catalog / Helper / Category / Url / Rewrite.php:

/**
* Join url rewrite to select
*
* @param Varien_Db_Select $select
* @param int $storeId
* @return Mage_Catalog_Helper_Category_Url_Rewrite
*/
public function joinTableToSelect(Varien_Db_Select $select, $storeId)
{
$select->joinLeft(
array('url_rewrite' => $this->_resource->getTableName('core/url_rewrite')),
'url_rewrite.category_id=main_table.entity_id'
);
$select->where('url_rewrite.is_system = ?', '1');
$select->where($this->_connection->quoteInto('url_rewrite.store_id = ?', (int)$storeId));
$select->where($this->_connection->prepareSqlCondition('url_rewrite.id_path', array('like' => 'category/%')));
$select->where('request_path = url_rewrite.request_path');

return $this;
}

2

在我们的案例中,它归结为以下缓慢的查询:

SELECT `main_table`.`entity_id`
      , `url_rewrite`.`request_path`
FROM `catalog_product_entity` AS `main_table` 
INNER JOIN `catalog_product_website` AS `w`
   ON main_table.entity_id = w.product_id 
LEFT JOIN `core_url_rewrite` AS `url_rewrite`
   ON url_rewrite.product_id = main_table.entity_id
   AND url_rewrite.is_system = 1
   AND url_rewrite.category_id IS NULL
   AND url_rewrite.store_id = 1
   AND url_rewrite.id_path LIKE 'product/%'
WHERE (w.website_id='1')

app / code / core / Mage / Sitemap / Model / Resource / Catalog / Product.php中获取

由于category_id IS NULL语句而挂起。MySQL由于某种原因未利用索引。

删除category_id IS NULL并设置id_path REGEXP'^ product / [0-9] + $'解决了该问题。

app / code / core / Mage / Catalog / Helper / Product / Url / Rewrite.php复制app / code / local / Mage / Catalog / Helper / Product / Url / Rewrite.php并添加以下功能:

public function joinTableToSelectPatch(Varien_Db_Select $select, $storeId)
{ 
$select->joinLeft(
    array('url_rewrite' => $this->_resource->getTableName('core/url_rewrite')),
    'url_rewrite.product_id = main_table.entity_id AND url_rewrite.is_system = 1 AND ' .
        $this->_connection->quoteInto('url_rewrite.store_id = ? AND ',
            (int)$storeId) .
        $this->_connection->prepareSqlCondition('url_rewrite.id_path', array('regexp' => '^product/[0-9]+$')),
    array('request_path' => 'url_rewrite.request_path'));
return $this;
}

然后将app / code / core / Mage / Sitemap / Model / Resource / Catalog / Product.php复制到app / code / local / Mage / Sitemap / Model / Resource / Catalog / Product.php,并将第72行更改为:

$urlRewrite->joinTableToSelectPatch($this->_select, $storeId);

最初取自https://www.goivvy.com/blog/solved-magento-stuck-generating-google-sitemap-large-website

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.