MySQL continua travado (consultas bloqueadas no envio de dados)

10

Eu tenho a seguinte situação:

Cerca de 5 vezes por semana (não relacionadas a qualquer situação específica, como limpeza de cache, aumento de tráfego), algumas consultas ficam presas ao enviar dados ( 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

o segundo:

> 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

Essas consultas estão relacionadas à geração do menu de navegação. Eles funcionam sem problemas e muito rápido o tempo todo.

Poucas vezes por mês, algumas outras consultas ficam presas aos dados de sedimentação ou aguardam o bloqueio da tabela:

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`)

(relacionado à pesquisa)

Informação adicional:

  • core_url_rewrite - 3M registros (30 sites, 100k produtos)
  • catalog_category_flat_store_ * - 2000 registros (o uso de categorias simples está ativado)

Isso está sendo executado em uma configuração usando vmware em algum hardware enorme (o mysql master possui 8 núcleos alocados e 64 GB de RAM, discos SSD em um armazenamento SAN), o mysql foi otimizado e é monitorado continuamente. No passado, houve alguns problemas relacionados à E / S (alguns problemas com o link entre os servidores e o armazenamento da SAN).

Não foi possível identificar o problema porque a execução no bare metal (sem virtualização, mesma configuração) isso nunca acontece, em condições de alto estresse (execução de cenários de teste de cerco + carga, sem cache).

Mais alguém com problemas semelhantes?

ATUALIZAR:

Toda a pesquisa foi movida para uma tabela temporária (para não bloquear a tabela principal usada pela produção e renomeia a tabela tmp). Portanto, o processo de reindexação não interfere nos visitantes que pesquisam no site. https://github.com/magendooro/magento-fulltext-reindex parabéns para carco

FlorinelChis
fonte
Você tem certeza, eles correram rápido? A alternativa pode ser o menu de navegação em cache. Afaik não é fácil para o uso de um índice, porque não há índice sobre category_ud, is_system e path. E o caminho é como, então o MySQL tem aqui um problema real. Eu não sou db export btw ;-) Apenas 2 centavos #
Fabian Blechschmidt
1
essa seleção é executada em menos de 1s. as consultas continuam se acumulando quando o primeiro estadias no envio de dados ...
FlorinelChis
1
FWIW Eu vi o mesmo problema.
philwinkle
@philwinkle, como está sua configuração de pesquisa? texto completo?
precisa saber é o seguinte
1
github.com/magendooro/magento-fulltext-reindex isso nos ajudou e decidiu publicar o código fonte.
FlorinelChis

Respostas:

4

Parece um erro / regressão central que vimos na versão 1.7, onde o bloco e o cache de coleção não estavam funcionando efetivamente no menu de navegação ( catalog/navigation/top.phtml).

Você pode testar removendo-o ou apenas capturar temporariamente a saída em um arquivo com um ob_starte servi-lo em um arquivo / memcache estático.

Além disso, o hardware que você está usando não parece enorme e parece sub especificado para o tamanho da loja que você possui. Provavelmente, também existe um gargalo de E / S - armazenamento SAN + rede congestionada = baixo desempenho.

-

Como solução bruta, você pode ajustar a classe de bloco para a navegação (despejo get_class($this)) top.phtmlpara identificá-la.

Isso permitirá o cache em todo o site, sem o cache no nível da categoria que a nova versão chamou. Também vale a pena remover a is_activeclasse do renderizador de árvore se você fizer isso para evitar que itens de menu aleatórios apareçam selecionados (e implemente uma alternativa 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;
}
Ben Lessani - Sonassi
fonte
anteriormente alocamos 32 núcleos e 92 Gb de ram (e alteramos a configuração do mysql de acordo com o mesmo resultado) - o servidor tem 64 núcleos e 184 gb de ram (é por isso que eu estava dizendo que é enorme) ... desculpe, eu não mencionei é o Magento Enterprise 1.12. monitoramos o tráfego de rede e não vimos nada apontando para um gargalo (já tivemos um problema antes, o conector de fibra não estava funcionando corretamente, foi substituído).
FlorinelChis
A empresa 1.12 é CE 1.7 - eles são a mesma base de código. Portanto, o bug afetará os dois. Experimente o que eu disse (codifique a navegação superior e desative as categorias na navegação em camadas) e você pode confirmar. Mais hardware não fará diferença se o software não estiver configurado corretamente para usá-lo.
Ben Lessani - Sonassi
Vou editar a minha resposta e adicionar um pouco hacky código para você usar para confirmar
Ben Lessani - Sonassi
É um bom lugar para começar, vou colocar algo no lugar e ver se ele ainda cai dentro de 1 semana :)
FlorinelChis
3

Substitua a função em

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;
}
Matthias Jaekle
fonte
2

No nosso caso, tudo se resumia a essa consulta lenta:

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')

de app / code / core / Mage / Sitemap / Model / Resource / Catalog / Product.php .

Trava por causa da instrução category_id IS NULL . O MySQL, por algum motivo, não utilizou um índice.

A remoção de category_id IS NULL e a configuração do id_path REGEXP '^ product / [0-9] + $' corrigiram o problema.

Copie app / code / core / Mage / Catalog / Helper / Product / Url / Rewrite.php para app / code / local / Mage / Catalog / Helper / Product / Url / Rewrite.php e adicione esta função:

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;
}

Em seguida, copie app / code / core / Mage / Sitemap / Model / Resource / Catalog / Product.php para app / code / local / Mage / Sitemap / Model / Resource / Catalog / Product.php e altere a linha 72 para:

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

Originalmente retirado de https://www.goivvy.com/blog/solved-magento-stuck-generating-google-sitemap-large-website

Konstantin Gerasimov
fonte