MySQL InnoDB no libera espacio en disco después de eliminar filas de datos de la tabla

140

Tengo una tabla MySQL que usa el motor de almacenamiento InnoDB; Contiene aproximadamente 2 millones de filas de datos. Cuando eliminé filas de datos de la tabla, no liberó el espacio en disco asignado. Tampoco se redujo el tamaño del archivo ibdata1 después de ejecutar el optimize tablecomando.

¿Hay alguna forma de recuperar espacio en disco de MySQL?

Estoy en una mala situación; esta aplicación se ejecuta en aproximadamente 50 ubicaciones diferentes y ahora aparece el problema de poco espacio en disco en casi todas ellas.

Sumit Deo
fuente
después de ejecutar el comando de optimización también, el tamaño del archivo ibdata1 no se redujo.
Sumit Deo
44
Creo que ese comentario sería mejor editado en su respuesta, y luego eliminado
Ben Millwood
posible duplicado de stackoverflow.com/q/11751792/82114 (pero este estuvo aquí primero)
FlipMcF
1
"Tampoco se redujo el tamaño del archivo ibdata1 después de ejecutar el comando de optimización de tabla", eso se debe a que innodb_file_per_tableestá apagado. La buena noticia es que esta opción está onpredeterminada en las versiones recientes de MySQL.
Contador م
Ejecuté "optimizar tabla xxxx" y recibí el mensaje "La tabla no es compatible con optimizar, haciendo recrear + analizar en su lugar". Después de ejecutar "du -h / var / lib / mysql" en un shell, pude ver que la base de datos se había reducido.
user1097111

Respuestas:

137

MySQL no reduce el tamaño de ibdata1. Nunca. Incluso si usa optimize tablepara liberar el espacio utilizado de los registros eliminados, lo reutilizará más tarde.

Una alternativa es configurar el servidor para usar innodb_file_per_table, pero esto requerirá una copia de seguridad, descartar la base de datos y restaurar. El lado positivo es que el archivo .ibd para la tabla se reduce después de un optimize table.

Leonel Martins
fuente
44
Documentos de MySQL 5.5 sobre el estado del modo de archivo por tabla de InnoDB "Para aprovechar las características del [archivo por tabla de InnoDB] para una tabla existente, puede activar la configuración de archivo por tabla y ejecutarla ALTER TABLE t ENGINE=INNODBen la tabla existente. " Esto implica que puede activar esta función, "convertir" las tablas existentes para usar un archivo InnoDB separado con el comando ALTER TABLE, luego OPTIMIZAR la tabla para reducir su tamaño. Sin embargo, una vez que haya terminado, tendría que descubrir cómo eliminar el (enorme) archivo InnoDB de origen ...
Josh
9
Supongo que esto técnicamente responde la pregunta, pero esperaría que la mayoría de las personas que buscan este tema busquen el proceso real para reducir / reclamar el espacio, que esta respuesta no proporciona.
Manachi
@Manachi El proceso es "configurar el servidor para usar innodb_file_per_table", "hacer una copia de seguridad" del servidor, "soltar las bases de datos", detener el mysql, eliminar .ibd, iniciar el servidor y restaurar las bases de datos. Con MySQL 5.5+ puede usar lo que dijo Josh, y después de cambiar todas las tablas, detenga el servidor, elimine el enorme .ibd y vuelva a iniciarlo.
Leonel Martins
39

Acabo de tener el mismo problema yo mismo.

Lo que sucede es que, incluso si elimina la base de datos, innodb aún no liberará espacio en disco. Tuve que exportar, detener mysql, eliminar los archivos manualmente, iniciar mysql, crear bases de datos y usuarios, y luego importar. Gracias a Dios, solo tenía 200 MB de filas, pero ahorró 250 GB de archivos innodb.

Fallar por diseño.

gilm
fuente
10
Sí, definitivamente es un fracaso.
trusktr
1
MySql 5.5 tiene el mismo problema: ejecuté "optimizar tabla" para reducir el uso del disco de una tabla de 28 GB. La operación probablemente intentó hacer un clon optimizado del original, y al hacerlo agotó todo el espacio en la partición. Ahora "optimizar tabla" falló y me quedé sin espacio en la partición, incluso después de que solté toda la base de datos ... muy decepcionante.
basilikode
1
Y más de 4 años después me encontré con el mismo problema con MySQL. MS SQL es similar: dba.stackexchange.com/questions/47310/…
Csaba Toth
24

Si no usa innodb_file_per_table , es posible recuperar espacio en disco, pero bastante tedioso, y requiere una cantidad significativa de tiempo de inactividad.

El Cómo es bastante profundo, pero pegué la parte relevante a continuación.

Asegúrese de conservar también una copia de su esquema en su volcado.

Actualmente, no puede eliminar un archivo de datos del espacio de tabla del sistema. Para disminuir el tamaño del espacio de tabla del sistema, use este procedimiento:

Use mysqldump para volcar todas sus tablas de InnoDB.

Detener el servidor

Elimine todos los archivos de espacio de tabla existentes, incluidos los archivos ibdata e ib_log. Si desea conservar una copia de seguridad de la información, copie todos los archivos ib * en otra ubicación antes de eliminar los archivos en su instalación de MySQL.

Elimine los archivos .frm para las tablas de InnoDB.

Configurar un nuevo espacio de tabla.

Reinicia el servidor.

Importar los archivos de volcado.

FlipMcF
fuente
Gracias por incluyendo los pasos - afaict el 'cómo' enlace no contiene esta información más
Aland
3

Diez años después y tuve el mismo problema. Lo resolví de la siguiente manera:

  • Optimicé todas las bases de datos restantes.
  • Reinicié mi computadora y MySQL en los servicios (Windows + r -> services.msc)

Eso es todo :)

Matheus Douglas
fuente
1

Otra forma de resolver el problema de la recuperación del espacio es, crear múltiples particiones dentro de la tabla - Particiones basadas en el rango, basadas en el valor y simplemente soltar / truncar la partición para reclamar el espacio, lo que liberará el espacio utilizado por todos los datos almacenados en la partición particular.

Habrá algunos cambios necesarios en el esquema de la tabla cuando introduzca la partición de su tabla, como: claves únicas, índices para incluir la columna de partición, etc.

Anand Immannavar
fuente
0

El año pasado también enfrenté el mismo problema en la versión mysql5.7 e ibdata1 ocupó 150 Gb. así que agregué deshacer espacios de tabla

Realice la copia de seguridad de Mysqldump
Detenga el servicio de mysql
Elimine todos los datos del directorio de datos
Agregue a continuación el parámetro deshacer tablespace en my.cnf actual

 #undo tablespace
  innodb_undo_directory =  /var/lib/mysql/
  innodb_rollback_segments = 128 
  innodb_undo_tablespaces = 3
  innodb_undo_logs = 128  
  innodb_max_undo_log_size=1G
  innodb_undo_log_truncate = ON

Iniciar mysql service
store mysqldump backup

Problema resuelto !!

Gajendra
fuente
-1

Hay varias formas de recuperar el espacio en disco después de eliminar datos de la tabla para el motor MySQL Inodb

Si no utiliza innodb_file_per_table desde el principio, deshacerse de todos los datos, eliminar todos los archivos, volver a crear la base de datos e importar datos nuevamente es la única forma (verifique las respuestas de FlipMcF arriba)

Si está utilizando innodb_file_per_table, puede intentar

  1. Si puede eliminar todos los datos, el comando truncar eliminará los datos y reclamará el espacio en disco por usted.
  2. Alterar el comando de tabla caerá y volverá a crear la tabla para que pueda recuperar el espacio en disco. Por lo tanto, después de eliminar datos, ejecute alter table que no cambie nada para liberar el disco duro (es decir: la tabla TBL_A tiene charset uf8, después de eliminar datos ejecute ALTER TABLE TBL_A charset utf8 -> este comando no cambia nada de su tabla pero hace que mysql vuelva a crear su tabla y recupere Espacio del disco
  3. Crea TBL_B como TBL_A. Inserte los datos seleccionados que desea conservar de TBL_A en TBL_B. Suelte TBL_A y cambie el nombre de TBL_B a TBL_A. De esta manera es muy efectivo si TBL_A y los datos que se necesitan eliminar son grandes (el comando eliminar en MySQL innodb es muy mal rendimiento)
Bùi Đức Khánh
fuente