В официальной документации:
https://devdocs.magento.com/guides/v2.3/extension-dev-guide/indexing.html
есть стемент:
`Allows tracking database changes for a certain entity (product, category and so on) and running change handler.
Emulates the materialized view technology for MySQL using triggers and separate materialization process (provides executing PHP code instead of SQL queries, which allows materializing multiple queries).`
MView расшифровывается как Materialized View, который представляет собой снимок базы данных в определенный момент времени.
https://en.wikipedia.org/wiki/Materialized_view
Зачем нам дублировать таблицы. Индексаторы обходятся дорого, особенно когда на страницах категорий есть трафик, клиенты размещают заказы, а администраторы сохраняют продукты. При сохранении продукта кеш становится недействительным (не по теме). В случае фондового индексатора, прежде чем он завершит выполнение, он отправляет идентификаторы сущностей, на которые влияют, как очищенные теги кэша (тип кэша полной страницы). В категории Magento 2.0 отправляются идентификаторы купленных продуктов. В Magento 2.1 отправляются идентификаторы продуктов.
Есть 2 таблицы MySQL, в которых хранятся коды и статусы индексатора:
indexer_state
mview_state
mview_state
работает Update by Schedule
в Admin> Система> Управление индексаторами
Update by Schedule
заставляет индексаторы работать в cron.
Есть 3 записи в Magento_Indexer/etc/contab.xml
:
<group id="index">
<job name="indexer_reindex_all_invalid" instance="Magento\Indexer\Cron\ReindexAllInvalid" method="execute">
<schedule>* * * * *</schedule>
</job>
<job name="indexer_update_all_views" instance="Magento\Indexer\Cron\UpdateMview" method="execute">
<schedule>* * * * *</schedule>
</job>
<job name="indexer_clean_all_changelogs" instance="Magento\Indexer\Cron\ClearChangelog" method="execute">
<schedule>0 * * * *</schedule>
</job>
</group>
indexer_reindex_all_invalid
работает на indexer_state
. По-прежнему необходимо запускать «нормальные» индексаторы в cron
indexer_update_all_views
работает на mview_state
indexer_clean_all_changelogs
- очищает журналы изменений, используемые mview_state
Обратите внимание , что групповые задания хрон индексатор запускается в отдельном процессе PHP, как заявлено в etc/contab_groups.xml
:
<use_separate_process>1</use_separate_process>
.
Таблицы изменений:
[indexer name]_cl
(с суффиксом _cl
). например cataloginventory_stock_cl
. Если у вас установлены индексы Update by Schedule
и вы сохраняете продукт в админке, вы увидите entity_id
этот продукт в этой таблице. Это большой круг, я думаю, разместить заказ или создать груз тоже добавит сюда запись.
Кто-то привел пример в официальном devdoc о том, как создавать новые материализованные представления и какие методы интерфейса требуются (не обращайте внимания на приведенное выше утверждение о заказах в фрагменте ниже):
<?php
<VendorName>\Merchandizing\Model\Indexer;
class Popular implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
{
public function executeFull(); //Should take into account all placed orders in the system
public function executeList($ids); //Works with a set of placed orders (mass actions and so on)
public function executeRow($id); //Works in runtime for a single order using plugins
public function execute($ids); //Used by mview, allows you to process multiple placed orders in the "Update on schedule" mode
}
Это будет иметь смысл:
//public function execute($ids); Used by mview, allows you to process multiple **entities** in the "Update on schedule" mode
}
где $ids
параметр имеет идентификаторы сущностей из *_cl
таблиц.
Какая связь между аннулированием кэша и индексаторами. Страницы категорий теперь полностью кэшируются (встроенный полный страничный кеш или через Varnish).
Есть \Magento\Indexer\Model\Processor\InvalidateCache::afterUpdateMview
:
/**
* Update indexer views
*
* @param \Magento\Indexer\Model\Processor $subject
* @return void
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterUpdateMview(\Magento\Indexer\Model\Processor $subject)
{
if ($this->moduleManager->isEnabled('Magento_PageCache')) {
$this->eventManager->dispatch('clean_cache_after_reindex', ['object' => $this->context]);
}
}
Вернуться к Magento\Indexer\Cron\UpdateMview::execute()
:
/**
* Regenerate indexes for all invalid indexers
*
* @return void
*/
public function execute()
{
$this->processor->updateMview();
}
Magento\Indexer\Model\Processor::updateMview()
:
/**
* Update indexer views
*
* @return void
*/
public function updateMview()
{
$this->mviewProcessor->update('indexer');
}
В app/etc/di.xml
есть:
<preference for="Magento\Framework\Mview\ProcessorInterface" type="Magento\Framework\Mview\Processor" />
/**
* Materialize all views by group (all views if empty)
*
* @param string $group
* @return void
*/
public function update($group = '')
{
foreach ($this->getViewsByGroup($group) as $view) {
$view->update();
}
}
Magento\Framework\Mview\ViewInterface
/**
* Materialize view by IDs in changelog
*
* @return void
* @throws \Exception
*/
public function update();
app/etc/di.xml
<preference for="Magento\Framework\Mview\ViewInterface" type="Magento\Framework\Mview\View" />
В Magento\Framework\Mview\View::update()
есть:
$action = $this->actionFactory->get($this->getActionClass());
$this->getState()->setStatus(View\StateInterface::STATUS_WORKING)->save();
..
$action->execute($ids);
..
Если вы ищете в vendor/
каталоге, Magento\Framework\Mview\ActionInterface
вы найдете, например, это:
В \Magento\CatalogInventory\Model\Indexer
:
class Stock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
В этом классе есть:
/**
* Execute materialization on ids entities
*
* @param int[] $ids
*
* @return void
*/
public function execute($ids)
{
$this->_productStockIndexerRows->execute($ids);
}
И похоже, что он восходит к «обычному» классу индексаторов - метод execute`, который используется MView.
О чистке кеша после Stock Indexer. Когда заказ размещается на кассе, количества вычитаются с помощью этого наблюдателя:\Magento\CatalogInventory\Observer\SubtractQuoteInventoryObserver
$itemsForReindex = $this->stockManagement->registerProductsSale(
$items,
$quote->getStore()->getWebsiteId()
);
Далее, другой наблюдатель запускает индексатор (но не напрямую в Mview / Indexer по расписанию):
\Magento\CatalogInventory\Observer\ReindexQuoteInventoryObserver
if ($productIds) {
$this->stockIndexerProcessor->reindexList($productIds);
}
В случае Mview, когда вычитаются новые количества SubtractQuoteInventoryObserver
, триггер MySQL (созданный для Mview) вставит строку в cataloginventory_stock_cl
, отмечая, что для этих идентификаторов приобретенного продукта необходимо выполнить переиндексацию (stock & fulltext). Для Mview создано множество триггеров MySQL. Увидеть их всех с SHOW TRIGGERS;
.
Когда товара нет на складе после оформления заказа, вы увидите 2 строки, вставленные в эту таблицу (Magento сохраняет 2 товара на складе у этих 2 наблюдателей).
Когда cron запускает фондовый индексатор в режиме Mview, идентификаторы затронутых продуктов (в M2.1) или идентификаторы категорий (в M2.0) отправляются в кэш, очищенные как теги кеша. Под кешем я подразумеваю полный тип кеша страниц. Пример: catalog_product_99
или другой формат тега кеша в зависимости от версии Magento. То же самое, когда Mview не включен.
\Magento\CatalogInventory\Model\Indexer\Stock\AbstractAction::_reindexRows
...
$this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]);
А у Magento_PageCache есть обозреватель, \Magento\PageCache\Observer\FlushCacheByTags
который будет очищать тэги типа кеша полной страницы. Это делает это для встроенного полного кеша страниц. Код, связанный с лаком, находится в \Magento\CacheInvalidate\Observer\InvalidateVarnishObserver
.
Существует бесплатное расширение, которое будет запрещать очистку кэша еще на складе продуктов после проверки покупателем:
https://github.com/daniel-ifrim/innovo-cache-improve
Очистка кеша только на отсутствующих товарах после оформления заказа была введена в стандартную версию Magento 2.2.x. См \Magento\CatalogInventory\Model\Indexer\Stock\CacheCleaner
.
Я думаю, что выполнение cron для indexer in Admin > Stores > Configuration > Advanced > System > Cron configuration options for group: index
должно быть установлено на более чем 1 минуту.
Mview
ссылается на материализованные представления , которыми являются таблицы индексов.