Aquí hay una respuesta más completa con respecto a InnoDB. Es un proceso un poco largo, pero puede valer la pena el esfuerzo.
Tenga en cuenta que /var/lib/mysql/ibdata1
es el archivo más ocupado en la infraestructura InnoDB. Normalmente alberga seis tipos de información:
- Datos de la tabla
- Índices de tabla
- MVCC (Control de concurrencia de versiones múltiples)
Datos
- Revertir segmentos
- Deshacer espacio
- Metadatos de tabla (diccionario de datos)
- Búfer de escritura doble (escritura en segundo plano para evitar la dependencia del almacenamiento en caché del sistema operativo)
- Insert Buffer (gestión de cambios en índices secundarios no únicos)
- Consulte la
Pictorial Representation of ibdata1
Arquitectura InnoDB
Mucha gente crea múltiples ibdata
archivos con la esperanza de una mejor gestión y rendimiento del espacio en disco, sin embargo, esa creencia es errónea.
¿Puedo ejecutar OPTIMIZE TABLE
?
Desafortunadamente, ejecutar OPTIMIZE TABLE
contra una tabla InnoDB almacenada en el archivo de espacio de tabla compartido ibdata1
hace dos cosas:
- Hace que los datos e índices de la tabla sean contiguos dentro de
ibdata1
- Hace
ibdata1
crecer porque los datos contiguos y las páginas de índice se añaden aibdata1
Sin embargo, puede separar los datos de tabla y los índices de tabla de ibdata1
y gestionarlos de forma independiente.
¿Puedo ejecutar OPTIMIZE TABLE
con innodb_file_per_table
?
Supongamos que agregara innodb_file_per_table
a /etc/my.cnf (my.ini)
. ¿Puede ejecutar OPTIMIZE TABLE
en todas las tablas de InnoDB?
Buenas noticias :Cuando ejecuta OPTIMIZE TABLE
con innodb_file_per_table
habilitado, esto producirá un .ibd
archivo para esa tabla. Por ejemplo, si tiene la tabla mydb.mytable
con un directorio de datos de /var/lib/mysql
, producirá lo siguiente:
/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
El .ibd
contendrá las páginas de datos y las páginas de índice para esa tabla. Genial.
Malas noticias :Todo lo que ha hecho es extraer las páginas de datos y las páginas de índice de mydb.mytable
de vivir en ibdata
. La entrada del diccionario de datos para cada tabla, incluido mydb.mytable
, aún permanece en el diccionario de datos (Consulte la Representación pictórica de ibdata1
). NO PUEDES SIMPLEMENTE ELIMINAR ibdata1
EN ESTE PUNTO !!! Tenga en cuenta que ibdata1
no se ha encogido en absoluto.
Limpieza de la infraestructura de InnoDB
Para reducir ibdata1
de una vez por todas debes hacer lo siguiente:
-
Volcado (por ejemplo, con
mysqldump
) todas las bases de datos en un.sql
archivo de texto (SQLData.sql
se usa a continuación) -
Elimina todas las bases de datos (excepto
mysql
yinformation_schema
) ADVERTENCIA :Como precaución, ejecute este script para asegurarse de que tiene todas las concesiones de usuario en su lugar:mkdir /var/lib/mysql_grants cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/. chown -R mysql:mysql /var/lib/mysql_grants
-
Inicie sesión en mysql y ejecute
SET GLOBAL innodb_fast_shutdown = 0;
(Esto eliminará por completo todos los cambios transaccionales restantes deib_logfile0
yib_logfile1
) -
Cerrar MySQL
-
Agregue las siguientes líneas a
/etc/my.cnf
(omy.ini
en Windows)[mysqld] innodb_file_per_table innodb_flush_method=O_DIRECT innodb_log_file_size=1G innodb_buffer_pool_size=4G
(Nota al margen:cualquiera que sea su configuración para
innodb_buffer_pool_size
, asegúrese deinnodb_log_file_size
es el 25% deinnodb_buffer_pool_size
.También:
innodb_flush_method=O_DIRECT
no está disponible en Windows) -
Eliminar
ibdata*
yib_logfile*
, Opcionalmente, puede eliminar todas las carpetas en/var/lib/mysql
, excepto/var/lib/mysql/mysql
. -
Inicie MySQL (Esto recreará
ibdata1
[10 MB por defecto] yib_logfile0
yib_logfile1
a 1G cada uno). -
Importar
SQLData.sql
Ahora, ibdata1
seguirá creciendo pero solo contendrá metadatos de tabla porque cada tabla InnoDB existirá fuera de ibdata1
. ibdata1
ya no contendrá datos e índices de InnoDB para otras tablas.
Por ejemplo, suponga que tiene una tabla InnoDB llamada mydb.mytable
. Si busca en /var/lib/mysql/mydb
, verá dos archivos que representan la tabla:
mytable.frm
(Encabezado del motor de almacenamiento)mytable.ibd
(Tabla de datos e índices)
Con el innodb_file_per_table
opción en /etc/my.cnf
, puede ejecutar OPTIMIZE TABLE mydb.mytable
y el archivo /var/lib/mysql/mydb/mytable.ibd
en realidad se encogerá.
He hecho esto muchas veces en mi carrera como administrador de bases de datos de MySQL. De hecho, la primera vez que hice esto, reduje un 50GB ibdata1
¡Archivo reducido a solo 500 MB!
Darle una oportunidad. Si tiene más preguntas sobre esto, solo pregunte. Confía en mí; esto funcionará tanto a corto como a largo plazo.
ADVERTENCIA
En el paso 6, si mysql no puede reiniciarse debido a mysql
el esquema comienza a descartarse, vuelva al Paso 2. Hizo la copia física de mysql
esquema. Puede restaurarlo de la siguiente manera:
mkdir /var/lib/mysql/mysql
cp /var/lib/mysql_grants/* /var/lib/mysql/mysql
chown -R mysql:mysql /var/lib/mysql/mysql
Regrese al Paso 6 y continúe
ACTUALIZACIÓN 2013-06-04 11:13 EDT
Con respecto a la configuración de innodb_log_file_size al 25% de innodb_buffer_pool_size en el Paso 5, esa regla general es bastante antigua.
El July 03, 2006
, Percona tenía un buen artículo por qué elegir un innodb_log_file_size adecuado . Más tarde, el Nov 21, 2008
, Percona siguió con otro artículo sobre cómo calcular el tamaño adecuado en función de la carga de trabajo máxima manteniendo los cambios de una hora
.
Desde entonces, he escrito publicaciones en DBA StackExchange sobre cómo calcular el tamaño del registro y dónde hice referencia a esos dos artículos de Percona.
Aug 27, 2012
:Ajuste adecuado para una tabla InnoDB de 30 GB en un servidor con 48 GB de RAMJan 17, 2013
:MySQL 5.5 - Innodb - innodb_log_file_size superior a 4GB combinado?
Personalmente, seguiría con la regla del 25 % para una configuración inicial. Luego, como la carga de trabajo se puede determinar con mayor precisión a lo largo del tiempo en producción, podría cambiar el tamaño los registros durante un ciclo de mantenimiento en solo minutos.