Programming

Reindex error: Row size too large

It happened to me that I wanted to reindex the product flat data and I got a PDOException, you can see the whole reindex error message bellow. I tried to find a solution and here are my findings. If you encountered the same problem now you know how to solve it. 1. The Error exception…

Paul Mestereaga

October 18, 2016

It happened to me that I wanted to reindex the product flat data and I got a PDOException, you can see the whole reindex error message bellow. I tried to find a solution and here are my findings. If you encountered the same problem now you know how to solve it.

1. The Error

exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1118 Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs' in /lib/Zend/Db/Statement/Pdo.php:228

2. The Cause

What is happening here is that we exceeded the row limit in the catalog_product_flat table. As stated in the exception message and here, the maximum row size is 65535. If we multiply the number of attributes by 255, which is the VARCHAR size, we need to get a value lower than 65535.

2. The Solution

There are two possible solutions. First check and see if you really need to have in the front-end all the attributes that you currently store in the flat table. If not then go and uncheck “Use in Layered Navigation”, “Used in Product Listing” and “Used for Sorting in Product Listing” for those attributes. Try to reindex again.

If that didn’t worked out, as it didn’t for me either, the things get a bit more complicated. We need to change the 255 default value for some attributes to decrease the row size.

A quick fix, but not really ideal, is to create a local copy of the indexer class and make the following updates:

// app/code/local/Mage/Catalog/Model/Resource/Product/Flat/Indexer.php
 
public function prepareFlatTable($storeId)
{
 
...
 
// Create table or modify existing one
if (!$this->_isFlatTableExists($storeId)) {
/** @var $table Varien_Db_Ddl_Table */
$table = $adapter->newTable($tableName);
foreach ($columns as $fieldName => $fieldProp) {
+       $skip = array('url_key','url_path','thumbnail','thumbnail_label','small_image','small_image_label','name','image_label');
+       if (!in_array($fieldName, $skip)) {
+           if ($fieldProp['length'] == "255") {
+               $fieldProp['length'] = "64";
+           }
+       } 
 
...
 
// Sort columns into added/altered/dropped lists
$describe   = $adapter->describeTable($tableName);
$addColumns     = array_diff_key($columns, $describe);
$dropColumns    = array_diff_key($describe, $columns);
$modifyColumns  = array();
foreach ($columns as $field => $fieldProp) {
+    $skip = array('url_key','url_path','thumbnail','thumbnail_label','small_image','small_image_label','name','image_label');
+    if (!in_array($field, $skip)) {
+        if ($fieldProp['length'] == "255") {
+            $fieldProp['length'] = "64";
+        }
+    }
 
...

The lines marked with + are the added ones. What this code does, it changes the default 255 value to 64. You can see also that I chose to exclude some attributes to not loose data integrity, because some of the attributes are larger than 64. I listed them in the $skip array, where you can put yours too.

Go ahead and reindex now. It will definitely work.

Related Posts

View Layer in Magento 2

7 Jun 2018

|

Paul Mestereaga

In this tutorial I will give an overview of the Magento 2 View Layer. We will learn how to build Blocks, Templates and Layouts.

Controllers in Magento 2

5 Feb 2018

|

Paul Mestereaga

Learn about the Controller Layer in Magento 2. Check the step by step tutorial on how to create Frontend and Backend controllers in Magento 2.