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

Эти запросы связаны с созданием меню навигации. Они бегают без проблем и очень быстро все время.

Несколько раз в месяц некоторые другие запросы застревают на данных об отмене или ожидают блокировки таблицы:

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 сайтов, 100 тыс. продуктов)
  • catalog_category_flat_store_ * - 2000 записей (использование плоских категорий включено)

Это выполняется на установке с использованием vmware на каком-то огромном оборудовании (мастер mysql имеет 8 выделенных ядер и 64 ГБ ОЗУ, SSD-диски в хранилище SAN), mysql был оптимизирован и постоянно отслеживается. В прошлом были некоторые проблемы, связанные с вводом / выводом (некоторые из-за связи между серверами и хранилищем SAN).

Мы не могли точно определить проблему, потому что при работе на голом железе (без виртуализации, с одинаковыми настройками) такого не бывает никогда, в условиях высокой нагрузки (при выполнении сценариев осады + нагрузочного тестирования, без кеша).

У кого-нибудь еще есть подобные проблемы?

ОБНОВИТЬ:

Поиск reindexAll был перемещен во временную таблицу (поэтому он не блокирует основную таблицу, используемую производством, а затем переименовывает таблицу tmp). Таким образом, процесс переиндексации не мешает посетителям, ищущим сайт. https://github.com/magendooro/magento-fulltext-reindex слава Carco

FlorinelChis
источник
Вы уверены, что они быстро побежали? Альтернативой может быть кеширование навигационного меню. Afaik - это нелегкое использование индекса, потому что нет индекса для category_ud, is_system и path. И путь, как, так что MySQL здесь реальная проблема на самом деле. Я не экспорт БД, кстати ;-) Всего 2цента
Фабиан Блехшмидт
1
этот выбор проходит под 1 с. запросы продолжают накапливаться, когда первый отправляет данные ...
FlorinelChis
1
FWIW Я видел ту же проблему.
Philwinkle
@philwinkle, как настроен поиск? полный текст?
FlorinelChis
1
github.com/magendooro/magento-fulltext-reindex это помогло нам и решило опубликовать исходный код.
FlorinelChis

Ответы:

4

Это выглядит как основная ошибка / регрессия, которую мы видели в 1.7, когда кеш блоков и сборов не работал эффективно для меню навигации ( catalog/navigation/top.phtml).

Вы можете проверить, удалив его, или просто временно записать вывод в файл с помощью ob_startи передать его из статического файла / memcache.

Кроме того, аппаратное обеспечение, которое вы используете, не звучит огромно и выглядит не так, как указано для размера вашего магазина. Там, вероятно, также есть узкое место ввода / вывода - хранилище 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 ядра и 92 ГБ оперативной памяти (и соответственно изменили конфигурацию mysql, тот же результат) - на сервере установлено 64 ядра и 184 ГБ оперативной памяти (поэтому я говорил, что он огромен) ... извините, я не упомянул это Magento Enterprise 1.12. мы отслеживали сетевой трафик, не видя ничего, указывающего на узкое место (раньше у нас была проблема, оптоволоконный разъем не работал должным образом, его заменили).
FlorinelChis
Предприятие 1.12 - это CE 1.7 - это одна и та же кодовая база. Так что ошибка затронет их обоих. Попробуйте то, что я сказал (жестко запишите верхнюю навигацию и отключите категории на многоуровневой навигации), и вы можете подтвердить. Больше оборудования не будет иметь значения, если программное обеспечение не будет правильно настроено для его использования.
Бен Лессани - Сонасси
Я собираюсь отредактировать свой ответ и добавить некоторый хакерский код, который вы сможете использовать для подтверждения
Бен Лессани - Sonassi
Это хорошее место для начала, я положу что-нибудь на место и посмотрю, не сработает ли оно в течение 1 недели :)
FlorinelChis
3

Заменить функцию на

Приложение / код / ​​ядро ​​/ Mage / Каталог / Helper / Категория / 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')

из приложения / кода / ядра / Маг / Карта сайта / Модель / Ресурс / Каталог / Product.php .

Зависает из-за оператора category_id IS NULL . MySQL по какой-то причине не использовал индекс.

Удаление category_id IS NULL и установка id_path REGEXP '^ product / [0-9] + $' устранили проблему.

Скопируйте приложение / code / core / Mage / Catalog / Helper / Product / Url / Rewrite.php в приложение / 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

Константин Герасимов
источник