Cómo reducir/purgar el archivo ibdata1 en MySQL
Estoy usando MySQL en localhost como una "herramienta de consulta" para realizar estadísticas en R, es decir, cada vez que ejecuto un script de R, creo una nueva base de datos (A), creo una nueva tabla (B), importo los datos a B , envío una consulta para obtener lo que necesito y luego descarto B y descarto A.
A mí me funciona bien, pero me doy cuenta de que el tamaño del archivo ibdata está aumentando rápidamente. No almacené nada en MySQL, pero el archivo ibdata1 ya superó los 100 MB.
Estoy usando una configuración MySQL más o menos predeterminada para la configuración, ¿hay alguna manera de poder reducir/purgar automáticamente el archivo ibdata1 después de un período de tiempo fijo?
Que ibdata1
no se reduzca es una característica particularmente molesta de MySQL. En realidad, el ibdata1
archivo no se puede reducir a menos que elimine todas las bases de datos, elimine los archivos y vuelva a cargar un volcado.
Pero puedes configurar MySQL para que cada tabla, incluidos sus índices, se almacene como un archivo separado. De esa manera ibdata1
no crecerá tanto. Según el comentario de Bill Karwin, esto está habilitado de forma predeterminada a partir de la versión 5.6.6 de MySQL.
Hace un tiempo hice esto. Sin embargo, para configurar su servidor para usar archivos separados para cada tabla, debe realizar cambios my.cnf
para habilitar esto:
[mysqld]
innodb_file_per_table=1
https://dev.mysql.com/doc/refman/5.6/en/innodb-file-per-table-tablespaces.html
Como desea recuperar el espacio, ibdata1
debe eliminar el archivo:
- Haga una revisión
mysqldump
de todas las bases de datos, procedimientos, desencadenantes, etc., excepto las bases de datosmysql
yperformance_schema
- Elimine todas las bases de datos excepto las 2 bases de datos anteriores
- detener mysql
- Eliminar
ibdata1
yib_log
archivos - iniciar mysql
- Restaurar desde el volcado
Cuando inicie MySQL en el paso 5, se recrearán los archivos ibdata1
y .ib_log
Ahora estás en condiciones de partir. Cuando crea una nueva base de datos para su análisis, las tablas se ubicarán en ibd*
archivos separados, no en archivos ibdata1
. Como normalmente descartas la base de datos poco después, los ibd*
archivos se eliminarán.
http://dev.mysql.com/doc/refman/5.1/en/drop-database.html
Probablemente hayas visto esto:
http://bugs.mysql.com/bug.php?id=1341
Al usar el comando ALTER TABLE <tablename> ENGINE=innodb
o OPTIMIZE TABLE <tablename>
se pueden extraer datos e indexar páginas de ibdata1 en archivos separados. Sin embargo, ibdata1 no se reducirá a menos que siga los pasos anteriores.
Respecto al information_schema
, eso no es necesario ni posible soltarlo. De hecho, son solo un montón de vistas de solo lectura, no tablas. Y no hay archivos asociados con ellos, ni siquiera un directorio de base de datos. Está informations_schema
utilizando el motor de base de datos de memoria y se descarta y se regenera al detener/reiniciar mysqld. Consulte https://dev.mysql.com/doc/refman/5.7/en/information-schema.html .
Agregando a la respuesta de John P ,
Para un sistema Linux, los pasos 1 a 6 se pueden realizar con estos comandos:
mysqldump -u [username] -p[root_password] [database_name] > dumpfilename.sql
mysqladmin -u [username] -p[root_password] drop [database_name]
sudo /etc/init.d/mysqld stop
sudo rm /var/lib/mysql/ibdata1
sudo rm /var/lib/mysql/ib_logfile*
sudo /etc/init.d/mysqld start
mysqladmin -u [username] -p[root_password] create [database_name]
mysql -u [username] -p[root_password] [database_name] < dumpfilename.sql
Advertencia: estas instrucciones harán que pierda otras bases de datos si tiene otras bases de datos en esta instancia de MySQL. Asegúrese de modificar los pasos 1,2 y 6,7 para cubrir todas las bases de datos que desea conservar.
Cuando eliminas tablas innodb, MySQL no libera espacio dentro del archivo ibdata, por eso sigue creciendo. Estos archivos casi nunca se reducen.
Cómo reducir un archivo ibdata existente:
https://dev.mysql.com/doc/refman/5.6/en/innodb-system-tablespace.html#innodb-resize-system-tablespace
Puede crear un script para esto y programar el script para que se ejecute después de un período de tiempo fijo, pero para la configuración descrita anteriormente parece que múltiples espacios de tabla son una solución más fácil.
Si usa la opción de configuración innodb_file_per_table
, crea múltiples espacios de tabla. Es decir, MySQL crea archivos separados para cada tabla en lugar de un archivo compartido. Estos archivos separados se almacenan en el directorio de la base de datos y se eliminan cuando elimina esta base de datos. Esto debería eliminar la necesidad de reducir/purgar archivos ibdata en su caso.
Más información sobre múltiples espacios de tabla:
https://dev.mysql.com/doc/refman/5.6/en/innodb-file-per-table-tablespaces.html