magento2: catalog_product_price index getting stuck
Preconditions and environment
- Magento 2.4.5-p1
- Large catalog (~8,000 products)
- All indexes set to “UPDATE BY SCHEDULE”
Steps to reproduce
Let indexes run on cron
Expected result
Indexes run successfully
Actual result
- Indexes get stuck at
catalog_product_price. - Product disappear from categories
Logs show the following errors:
[2022-10-13T09:59:05.759670+00:00] main.ERROR: Cron Job indexer_update_all_views has an error: SQLSTATE[21S01]: Insert value list does not match column list:
1136 Column count doesn't match value count at row 1, query was: INSERT INTO `catalog_product_index_price` SELECT `ip_tmp`.* FROM `catalog_product_index_price_temp` AS `ip_tmp` ON DUPLICATE KEY UPDATE `tax_class_id` = VALUES(`tax_class_id`), `price` = VALUES(`price`), `final_price` = VALUES(`final_price`), `min_price` = VALUES(`min_price`), `max_price` = VALUES(`max_price`), `tier_price` = VALUES(`tier_price`). Statistics: {"sum":0,"count":1,"realmem":0,"emalloc":0,"realmem_start":256376832,"emalloc_start":237979584} [] []
[2022-10-13T09:59:05.760119+00:00] main.CRITICAL: PDOException: SQLSTATE[21S01]: Insert value list does not match column list: 1136 Column count doesn't match value count at row 1 in /vendor/magento/framework/DB/Statement/Pdo/Mysql.php:90
Stack trace:
#0 /vendor/magento/framework/DB/Statement/Pdo/Mysql.php(90): PDOStatement->execute()
#1 /vendor/magento/framework/DB/Statement/Pdo/Mysql.php(106): Magento\Framework\DB\Statement\Pdo\Mysql->Magento\Framework\DB\Statement\Pdo\{closure}()
#2 /vendor/magento/framework/DB/Statement/Pdo/Mysql.php(91): Magento\Framework\DB\Statement\Pdo\Mysql->tryExecute(Object(Closure))
#3 /vendor/magento/zendframework1/library/Zend/Db/Statement.php(313): Magento\Framework\DB\Statement\Pdo\Mysql->_execute(Array)
#4 /vendor/magento/zendframework1/library/Zend/Db/Adapter/Abstract.php(480): Zend_Db_Statement->execute(Array)
#5 /vendor/magento/zendframework1/library/Zend/Db/Adapter/Pdo/Abstract.php(247): Zend_Db_Adapter_Abstract->query('INSERT INTO `ca...', Array)
#6 /vendor/magento/framework/DB/Adapter/Pdo/Mysql.php(564): Zend_Db_Adapter_Pdo_Abstract->query('INSERT INTO`ca...', Array)
#7 /vendor/magento/framework/DB/Adapter/Pdo/Mysql.php(634): Magento\Framework\DB\Adapter\Pdo\Mysql->_query('INSERT INTO `ca...', Array)
#8 /vendor/magento/module-catalog/Model/Indexer/Product/Price/AbstractAction.php(193): Magento\Framework\DB\Adapter\Pdo\Mysql->query('INSERT INTO `ca...')
#9 /vendor/magento/module-catalog/Model/Indexer/Product/Price/AbstractAction.php(417): Magento\Catalog\Model\Indexer\Product\Price\AbstractAction->_syncData(Array)
#10 /vendor/magento/module-catalog/Model/Indexer/Product/Price/Action/Rows.php(126): Magento\Catalog\Model\Indexer\Product\Price\AbstractAction->_reindexRows(Array)
#11 /vendor/magento/module-catalog/Model/Indexer/Product/Price.php(68): Magento\Catalog\Model\Indexer\Product\Price\Action\Rows->execute(Array)
#12 /vendor/magento/framework/Interception/Interceptor.php(58): Magento\Catalog\Model\Indexer\Product\Price->execute(Array)
#13 /vendor/magento/framework/Interception/Interceptor.php(138): Magento\Catalog\Model\Indexer\Product\Price\Interceptor->___callParent('execute', Array)
Next Zend_Db_Statement_Exception: SQLSTATE[21S01]: Insert value list does not match column list: 1136 Column count doesn't match value count at row 1, query was: INSERT INTO `catalog_product_index_price` SELECT `ip_tmp`.* FROM `catalog_product_index_price_temp` AS `ip_tmp` ON DUPLICATE KEY UPDATE `tax_class_id` = VALUES(`tax_class_id`), `price` = VALUES(`price`), `final_price` = VALUES(`final_price`), `min_price` = VALUES(`min_price`), `max_price` = VALUES(`max_price`), `tier_price` = VALUES(`tier_price`) in /vendor/magento/framework/DB/Statement/Pdo/Mysql.php:109
Stack trace:
#0 /vendor/magento/framework/DB/Statement/Pdo/Mysql.php(91): Magento\Framework\DB\Statement\Pdo\Mysql->tryExecute(Object(Closure))
#1 /vendor/magento/zendframework1/library/Zend/Db/Statement.php(313): Magento\Framework\DB\Statement\Pdo\Mysql->_execute(Array)
#2 /vendor/magento/zendframework1/library/Zend/Db/Adapter/Abstract.php(480): Zend_Db_Statement->execute(Array)
#3 /vendor/magento/zendframework1/library/Zend/Db/Adapter/Pdo/Abstract.php(247): Zend_Db_Adapter_Abstract->query('INSERT INTO `ca...', Array)
#4 /vendor/magento/framework/DB/Adapter/Pdo/Mysql.php(564): Zend_Db_Adapter_Pdo_Abstract->query('INSERT INTO`ca...', Array)
#5 /vendor/magento/framework/DB/Adapter/Pdo/Mysql.php(634): Magento\Framework\DB\Adapter\Pdo\Mysql->_query('INSERT INTO `ca...', Array)
#6 /vendor/magento/module-catalog/Model/Indexer/Product/Price/AbstractAction.php(193): Magento\Framework\DB\Adapter\Pdo\Mysql->query('INSERT INTO `ca...')
#7 /vendor/magento/module-catalog/Model/Indexer/Product/Price/AbstractAction.php(417): Magento\Catalog\Model\Indexer\Product\Price\AbstractAction->_syncData(Array)
#8 /vendor/magento/module-catalog/Model/Indexer/Product/Price/Action/Rows.php(126): Magento\Catalog\Model\Indexer\Product\Price\AbstractAction->_reindexRows(Array)
#9 /vendor/magento/module-catalog/Model/Indexer/Product/Price.php(68): Magento\Catalog\Model\Indexer\Product\Price\Action\Rows->execute(Array)
#10 /vendor/magento/framework/Interception/Interceptor.php(58): Magento\Catalog\Model\Indexer\Product\Price->execute(Array)
#11 /vendor/magento/framework/Interception/Interceptor.php(138): Magento\Catalog\Model\Indexer\Product\Price\Interceptor->___callParent('execute', Array)
Changing catalog_product_price index to “Update on Save” seems to work as a temporary workaround.
Additional information
No response
Release note
No response
Triage and priority
- Severity: S0 - Affects critical data or functionality and leaves users without workaround.
- Severity: S1 - Affects critical data or functionality and forces users to employ a workaround.
- Severity: S2 - Affects non-critical data or functionality and forces users to employ a workaround.
- Severity: S3 - Affects non-critical data or functionality and does not force users to employ a workaround.
- Severity: S4 - Affects aesthetics, professional look and feel, “quality” or “usability”.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 2
- Comments: 34 (4 by maintainers)
Hello, I’m having this problem updating product inventory directly using
Magento\CatalogInventory\Api\StockRegistryInterface::updateStockItemBySku(). InMagento\CatalogInventory\Model\ResourceModel\Stock\Item::_afterSave(), there’s a check to see if the data changed for any of the fields [‘is_in_stock’,‘use_config_manage_stock’,‘manage_stock’], and if so it runs the functionreindexRow()from the priceIndexProcessor. I’ve been having trouble finding someone discussing this problem until I stumbled across your post here, and instead I’ve been somewhat convinced that the error lies in some of our custom modules against the recent 2.4.5 update and spending most of my time reviewing them. But, all paths appear to lead back to the Magento_CatalogInventory module.I believe this problem was introduced by the commit https://github.com/magento/magento2/commit/263c17fd05152ff06b2ce2f32611094d371ba665, where the db_schema.xml was modified, and an “id” column was added to the catalog_product_index_price_tmp table (and the PK set against just that column), which makes the schema for that table different than catalog_product_index_price. Through the
Magento\Catalog\Model\Indexer\Product\Price\AbstractAction::reindexRow()a temporary table is created based on the table catalog_product_index_price_tmp, named catalog_product_index_price_temp, and that table is then used in anINSERT INTO tbl SELECT * FROM othertblquery. Since the schemas now differ, you get this quite colossal problem.We don’t seem to be seeing this error running a full reindex as that code path eventually leads to the function
Magento\Catalog\Model\Indexer\Product\Price\AbstractAction::_insertFromTable(), which determines the columns to use for the insert directly from the target table (catalog_product_index_price), instead of just using the mighty *, and the adjustment to the schema for catalog_product_index_price_tmp does not matter there. I’m really not sure why you’re seeing this problem where you are, and now I’m scouring my logs to see if I’m getting this error outside the case where I’m adjusting inventory quantities directly, and I don’t seem to be - but I still think this boils down to the same problem.I’ve been looking to put together a composer patch to get the
Magento\Catalog\Model\Indexer\Product\Price\AbstractAction::_syncData()function to use the_insertFromTable()instead, but this is a bit deeper into the M2 code than I’m generally comfortable, and hoping to get a bit of discussion confirming the problem and suggested solution. My best guess is that throughout those “optimizations”, this particular product-specific reindexing was simply overlooked.This caused a similar problem for my company (running Magento 2.4.6-p3). The new id primary key on the temporary table slowed down the inventory indexer to the point where it could never complete. We reverted the db_schema.xml so that the 3 previous primary keys were restored then rebuilt the codebase (you need to drop the catalog_product_index_price_tmp table on the first run). Then the inventory indexer ran fine, usually completing in approximatley 5 minutes.
Any update on the target version for this? Not fixed in 2.4.6-p1. Though I suppose it doesn’t matter as the custom indexer model workaround is easy enough.
Edit: To be explicit, my workaround for this was adding this in my custom product type <type> tag:
Hello @vseager,
We have found a way to reproduce the issue. We have tried it in Magento 2.4.5-p1 and 2.4-develop branch and the issue is reproducible for us. We have made the below module in order to reproduce it: Adobe.zip
app\codefolder.bin/magento setup:upgradecommandn98-magerun2 sys:cron:run indexer_update_all_viewsThe error is reproducible:Internal JIRA has been created to address this issue:
https://jira.corp.adobe.com/browse/ACP2E-1401
The team has started working on it and a hotfix will share soon with the community.
Thanks
Hello,
As I can see this issue got fixed in the scope of the internal Jira ticket ACP2E-1401 by the internal team Related commits: https://github.com/magento/magento2/search?q=ACP2E-1401&type=commits
Based on the Jira ticket, the target version is 2.4.6.
Thanks
I have two changes that I’m using on a site now to resolve this problem. The first one is a composer patch against magento/module-catalog, and just adjusts that
_syncData()function to target specific columns instead of using the “SELECT *”. I don’t believe it’s much of a performance knock as the DDL information that gets queried is pretty heavily cached. This requirescweagans/composer-patches. Contents I am using are:Next, for my modules defining custom product types, I’m adding a definition for an
<indexerModel>inside the<type>declaration in the etc/product_types.xml file, looks like<indexerModel instance="Client\Project\Model\ResourceModel\ProductIndexerPrice\ProjectPrice" />. This requires creating that ProjectPrice class, extendingMagento\Catalog\Model\ResourceModel\Product\Indexer\Price\SimpleProductPriceand overriding the__construct()enough to adjust the default value of the$productTypeargument to set it to the machine type of your custom product type. If you don’t do that, it will fail to generate any records for those products in the price index because part of the query it generates filters to only the product type that is specified for that index. I have not found a way to declare that argument for the original SimpleProductPrice class so that it only affects products of that type - I don’t know that it’s possible. This appears to be the easy way around it.Hopefully this helps somebody - and if anyone sees anything troubling with these adjustments, by all means please let me know!
Hi @pmonosolo , Verified the issue again on Magento 2.4-develop instance with the mentioned steps by you but still no luck. Steps performed:
Hey @pmonosolo, I’d suggest taking a look at that #36370 mentioned above by hostep - that’s generally the same thing at least when I reviewed it earlier, they’re trying to solve the same problem and that is code that I’d expect to actually get committed in the future. It would be useful for them to get feedback on that as well - it should be pretty easy to pull those changes as a patch. Either way hopefully you have success, good luck!
Hi @alek-s-andr , you might peek at the “etc/product_types.xml” file in that third party module, see if there is a declaration for an
<indexerModel>inside the<type>declaration for the product type. It would probably be useful to communicate with the vendor for that module and reference this github issue to see if they can confirm the problem and provide a fix. Even if an indexerModel is defined, if it does not implementMagento\Framework\Indexer\DimensionalIndexerInterfaceor inherit from a class that does, it will likely end up going through that function which appears to be causing problems. Good luck!Hello @engcom-November, I’d suggest that the conditions to reproduce this issue include the adjustment of some products to change their is_in_stock/manage_stock/etc values. The full
php bin/magento indexer:reindexruns through a different set of functions, and the specific calls that get to the erroring code require that you’re only reindexing specific products at a time, rather than all of them.If you have your indexes (at least price index) configured to update on save, you can simply take a product that is not managed by inventory (default not managed), go into the product settings and change the configuration to manage inventory, leave the qty at zero so it will be calculated to out of stock, save it, and now it’s no longer in categories. Do a full reindex (
php bin/magento indexer:reindex) afterwards and it will fix it and the product will show up again.The important thing is that you do not see exceptions on the frontend or when running the CLI, because they are caught inside the indexer and written to logs. It does not bubble up from there, and there’s no indication in calling code that there was any problem whatsoever, you have to be looking through the logs to see that anything went wrong or see the symptoms from the frontend.