Error de tamaño de fila con MySQL

11

Estoy ejecutando un servidor MySQL en mi Macbook (para probar). La versión es 5.6.20 de Homebrew. Empecé a encontrarme con errores de "Tamaño de fila demasiado grande" y pude reducirlo a este caso de prueba. Mesa:

mysql> describe test;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| id    | int(11)  | NO   | PRI | NULL    | auto_increment |
| stuff | longtext | YES  |     | NULL    |                |
+-------+----------+------+-----+---------+----------------+

Estado de la tabla:

mysql> show table status where Name = 'test';
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time         | Update_time | Check_time | Collation       | Checksum | Create_options | Comment |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| test | InnoDB |      10 | Compact    |    1 |          16384 |       16384 |               0 |            0 |   5242880 |              2 | 2014-08-28 23:51:12 | NULL        | NULL       | utf8_general_ci |     NULL |                |         |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+

El error stuffque obtengo cuando intento insertar una fila en la tabla donde la columna tiene más de 5033932 bytes.

mysql> select length(stuff) from test;
+---------------+
| length(stuff) |
+---------------+
|       5033932 |
+---------------+

mysql> update test set stuff = concat(stuff, 'a');
ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.

He buscado este error, la mayoría de las respuestas implican tener demasiadas columnas TEXT, y cada una tiene 768 bytes almacenados en línea. Como puede ver, ese no es el caso para mí. Además, el número 5033932 permanece igual independientemente del número de columnas que tengo en la tabla. En mi aplicación original, había cinco columnas, y las actualizaciones aún fallaban cuando el tamaño de la columna excedía 5033932.

También he visto personas resolver el problema cambiando los formatos de fila, lo que intentaré en un momento, pero me gustaría entender exactamente qué está causando este error.

¡Gracias por adelantado!

geoffliu
fuente

Respuestas:

12

Un cambio en las notas de la versión 5.6.20:

Rehacer las escrituras de registros para campos BLOB grandes almacenados externamente podría sobrescribir el punto de control más reciente. El parche 5.6.20 limita el tamaño de redo log BLOB escribe al 10% del tamaño del archivo de redo log. El parche 5.7.5 soluciona el error sin imponer una limitación. Para MySQL 5.5, el error sigue siendo una limitación conocida.

Como resultado del límite de escritura BLOB redo log introducido para MySQL 5.6, innodb_log_file_size debe establecerse en un valor mayor que 10 veces el tamaño de datos BLOB más grande encontrado en las filas de sus tablas más la longitud de otros campos de longitud variable (VARCHAR, VARBINARY y campos de tipo TEXTO). De lo contrario, podrían producirse errores de "Tamaño de fila demasiado grande".

(énfasis mío)

El valor predeterminado para innodb_log_file_sizees 50331648, lo que significa que el valor BLOB / TEXT más grande que puede crear, independientemente del tipo de datos, está cerca de 5033164, y descubrió que el valor preciso es 5033932. Supongo que internamente el cálculo involucra algún factor fudge.

Por lo tanto, debe aumentar innodb_log_file_sizesi desea almacenar datos BLOB / TEXT más grandes. Afortunadamente, cambiar el tamaño del archivo de registro es mucho más fácil en 5.6 que en versiones anteriores de InnoDB. Simplemente agregue una línea en my.cnf con el nuevo valor y reinicie mysqld.

Bill Karwin
fuente
pequeño aviso, debe reiniciar o detener y comenzar de nuevo para permitir que el cambio se vea afectado, la recarga no funciona
Hieu Vo
1
Este límite de tamaño de rehacer se reduce al 10% del total combinado innodb_log_file_size (innodb_log_file_size * innodb_log_files_in_group) de mysql 5.6.22. Y el bloque largo puede tener una longitud máxima de 4294967295 (2 ^ 32 - 1) caracteres, es decir, 4 GB alrededor. Para almacenar este valor de bloque largo, debemos tener un mínimo combinado de 40 GB innodb_log_file_size (innodb_log_file_size * innodb_log_files_in_group).
kasi