sql >> Base de Datos >  >> RDS >> Mysql

¿Cómo:Limpiar un motor de almacenamiento mysql InnoDB?

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:

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 a ibdata1

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:

  1. Volcado (por ejemplo, con mysqldump ) todas las bases de datos en un .sql archivo de texto (SQLData.sql se usa a continuación)

  2. Elimina todas las bases de datos (excepto mysql y information_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
    
  3. Inicie sesión en mysql y ejecute SET GLOBAL innodb_fast_shutdown = 0; (Esto eliminará por completo todos los cambios transaccionales restantes de ib_logfile0 y ib_logfile1 )

  4. Cerrar MySQL

  5. Agregue las siguientes líneas a /etc/my.cnf (o my.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 de innodb_log_file_size es el 25% de innodb_buffer_pool_size .

    También:innodb_flush_method=O_DIRECT no está disponible en Windows)

  6. Eliminar ibdata* y ib_logfile* , Opcionalmente, puede eliminar todas las carpetas en /var/lib/mysql , excepto /var/lib/mysql/mysql .

  7. Inicie MySQL (Esto recreará ibdata1 [10 MB por defecto] y ib_logfile0 y ib_logfile1 a 1G cada uno).

  8. 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.

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.