`ERROR 1114 (HY000) la tabla ... está llena` con innodb_file_per_table establecido en autoextend


26

Tengo una base de datos MySQL que contiene una gran cantidad de datos (100-200GB, un montón de mediciones científicas). La gran mayoría de los datos se almacenan en una tabla Sample. Ahora estoy creando una réplica esclava de la base de datos y quería aprovechar las ventajas innodb_file_per_tabledurante el proceso. Así que configuré innodb_file_per_tablemi configuración esclava e importé el volcado de la base de datos. Para mi sorpresa, falló con

ERROR 1114 (HY000) en la línea 5602: la tabla 'Muestra' está llena

El archivo Sample.ibdtiene actualmente unos 93 GB, con más de 600 GB de espacio libre disponible en la partición, por lo que no es un problema de espacio libre en el disco. Tampoco parece estar alcanzando ningún tipo de límite del sistema de archivos (estoy usando ext4).

Le agradecería cualquier idea de cuál podría ser la causa o qué investigar.


Actualización: estoy usando mysql Ver 14.14 Distrib 5.1.66, for debian-linux-gnu (x86_64).

SELECT @@datadir; -- returns `/home/var/lib/mysql/`
SHOW VARIABLES LIKE '%innodb_data_file_path%'; -- ibdata1:10M:autoextend 

df -h /home/var/lib/mysql/
768G   31G  699G   5% /home

Respuestas:


33

HECHOS

Dijiste que estás usando ext4. El límite de tamaño del archivo es de 16 TB. Por lo tanto, Sample.ibdno debe estar lleno.

Dijiste tu innodb_data_file_pathes ibdata1:10M:autoextend. Por lo tanto, el archivo ibdata1 en sí mismo no tiene límite para su tamaño, excepto del sistema operativo.

¿Por qué viene este mensaje? Observe que el mensaje es "La tabla ... está llena", no "El disco ... está lleno". Esta condición de tabla completa es desde un punto de vista lógico . Piensa en InnoDB. ¿Qué interacciones están sucediendo?

Supongo que InnoDB está intentando cargar 93GB de datos como una sola transacción. ¿De dónde Table is Fullemanaría el mensaje? Vería el ibdata1, no en términos de su tamaño físico (que ya descartó), sino en términos de qué límites de transacción se están alcanzando.

¿Qué hay dentro de ibdata1 cuando innodb_file_per_table está habilitado y carga nuevos datos en MySQL?

  • Diccionario de datos
  • Buffer de doble escritura
    • Red de seguridad para prevenir la corrupción de datos
    • Ayuda a evitar el sistema operativo para el almacenamiento en caché
  • Insertar memoria intermedia (racionaliza los cambios en los índices secundarios)
  • Segmentos de reversión
  • Deshacer registros
  • Haga clic aquí para ver una representación pictórica de ibdata1

Mis sospechas me dicen que los registros de deshacer y / o los registros de rehacer son los culpables.

¿Qué son estos registros? De acuerdo con el libro

sxs

Capítulo 10: "Motores de almacenamiento" Página 203 Los párrafos 3,4 dicen lo siguiente:

El motor InnoDB mantiene dos tipos de registros: un registro de deshacer y un registro de rehacer. El propósito de un registro de deshacer es revertir las transacciones, así como mostrar las versiones anteriores de los datos para consultas que se ejecutan en el nivel de aislamiento de transacciones que lo requiere. El código que maneja el registro de deshacer se puede encontrar en storage / innobase / buf / log / log0log.c .

El propósito del registro de rehacer es almacenar la información que se utilizará en la recuperación de fallas. Permite que el proceso de recuperación vuelva a ejecutar las transacciones que pueden haberse completado o no antes del bloqueo. Después de volver a ejecutar esas transacciones, la base de datos se lleva a un estado coherente. El código que trata con el registro de rehacer se puede encontrar en storage / innobase / log / log0recv.c .

ANÁLISIS

Hay 1023 registros de deshacer dentro de ibdata1 (consulte Segmentos de reversión y espacio de deshacer) . Como los registros de deshacer guardan copias de los datos tal como aparecieron antes de la recarga, todos los registros de deshacer de 1023 han alcanzado su límite. Desde otra perspectiva, todos los registros de deshacer 1023 pueden estar dedicados a la única transacción que carga la Sampletabla.

PERO ESPERA...

Probablemente esté diciendo "Estoy cargando una Samplemesa vacía ". ¿Cómo están involucrados los registros de deshacer? Antes de Samplecargar la tabla con 93 GB de datos, estaba vacía. La representación de cada fila que no existía debe ocupar un espacio de limpieza en los registros de deshacer. Llenar 1023 Deshacer registros parece trivial dada la cantidad de datos que se vierte ibdata1. No soy la primera persona en sospechar esto:

De la documentación de MySQL 4.1, tenga en cuenta Posted by Chris Calender on September 4 2009 4:25pm:

Tenga en cuenta que en 5.0 (anterior a 5.0.85) y en 5.1 (anterior a 5.1.38), podría recibir el error "tabla está llena" para una tabla InnoDB si InnoDB se queda sin ranuras de deshacer (error # 18828).

Aquí está el informe de errores para MySQL 5.0: http://bugs.mysql.com/bug.php?id=18828

SUGERENCIAS

Cuando cree el mysqldump de la Sampletabla, use --no-autocommit

mysqldump --no-autocommit ... mydb Sample > Sample.sql

Esto pondrá un explícito COMMIT;después de cada INSERT. Luego, vuelva a cargar la mesa.

Si esto no funciona ( no te va a gustar esto ), haz esto

mysqldump --no-autocommit --skip-extended-insert ... mydb Sample > Sample.sql

Esto hará que cada INSERT tenga solo una fila. Mysqldump será mucho más grande (más de 10 veces más grande) y su recarga podría tardar entre 10 y 100 veces más.

En cualquier caso, esto evitará que los registros de deshacer se inunden.

Darle una oportunidad !!!

ACTUALIZACIÓN 2013-06-03 13:05 EDT

SUGERENCIA ADICIONAL

Si la tabla del sistema InnoDB (también conocida como ibdata1) alcanza un límite de tamaño de archivo y no se pueden usar los registros de deshacer, puede agregar otro espacio de tabla del sistema (ibdata2).

Acabo de encontrarme con esta situación hace solo dos días. Actualicé mi publicación anterior con lo que hice: consulte Diseño de base de datos: creación de varias bases de datos para evitar el dolor de cabeza del límite en el tamaño de la tabla

En esencia, debe cambiar innodb_data_file_path para acomodar un nuevo archivo de espacio de tabla del sistema. Déjame explicarte cómo:

GUIÓN

En el disco (ext3), el servidor de mi cliente tenía lo siguiente:

[root@l*****]# ls -l ibd*
-rw-rw---- 1 s-em7-mysql s-em7-mysql     362807296 Jun  2 00:15 ibdata1
-rw-rw---- 1 s-em7-mysql s-em7-mysql 2196875759616 Jun  2 00:15 ibdata2

El escenario fue

innodb_data_file_path=ibdata1:346M;ibdata2:500M:autoextend:max:10240000M

Tenga en cuenta que ibdata2creció a 2196875759616 que es 2145386484M.

Tuve que incrustar el tamaño del archivo ibdata2en innodb_data_file_path y agregaribdata3

innodb_data_file_path=ibdata1:346M;ibdata2:2196875759616;ibdata3:10M:autoextend

Cuando reinicié mysqld, funcionó:

[root@l*****]# ls -l ibd*
-rw-rw---- 1 s-em7-mysql s-em7-mysql     362807296 Jun  3 17:02 ibdata1
-rw-rw---- 1 s-em7-mysql s-em7-mysql 2196875759616 Jun  3 17:02 ibdata2
-rw-rw---- 1 s-em7-mysql s-em7-mysql   32315015168 Jun  3 17:02 ibdata3

En 40 horas, ibdata3creció a 31G. MySQL estaba nuevamente trabajando.


Supongo que por el nombre del propietario, su cliente estaba usando una herramienta de monitoreo próxima ... Gracias, esto parece haber solucionado un problema también para mí.
Steve

Me pregunto si esto sigue siendo un problema (espero que no)
Evan Carroll

3

Tuve el mismo problema y solo hice una cosa y funcionó.

Parece tener un tamaño máximo demasiado bajo para su innodb_data_file_pathen su my.cnfarchivo de configuración. Simplemente cambie el siguiente código:

innodb_data_file_path = ibdata1:10M:autoextend:max:512M

Nota importante No puede alojar más 512MBde datos en todas las InnoDB tablas combinadas.

También puede cambiar a un esquema innodb por tabla usando innodb_file_per_table.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.