2010-10-13 26 views
119

¿Es posible limpiar un motor de almacenamiento mysql innodb para que no almacene datos de tablas eliminadas?Cómo: limpiar un motor de almacenamiento mysql InnoDB?

¿O tengo que reconstruir una nueva base de datos cada vez?

+0

¿Qué le hace pensar que MySQL está almacenando datos de tablas eliminadas? –

+1

Si elimino un montón de tablas enormes, mis archivos de almacenamiento InnoDB no se reducen –

+2

@RobertMunteanu: vea http://bugs.mysql.com/bug.php?id=1341 – Max

Respuesta

309

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 de InnoDB. Normalmente se aloja seis tipos de información:

  • Tabla de Datos
  • índices de tablas
  • MVCC (Multiversioning Concurrency Control) datos
    • segmentos de rollback
    • espacio de deshacer
  • la tabla de metadatos (diccionario de datos)
  • doble Escribir Buffer (fondo escritura para evitar la dependencia de almacenamiento en caché OS)
  • Insertar Buffer (gestión de los cambios en los índices secundarios no únicos)
  • Ver el Pictorial Representation of ibdata1

InnoDB Arquitectura

InnoDB Architecture

Muchas personas crean múltiples archivos ibdata con la esperanza de una mejor administración y rendimiento del espacio de disco, sin embargo, esa creencia es errónea.

¿Puedo ejecutar OPTIMIZE TABLE?

Desafortunadamente, corriendo OPTIMIZE TABLE contra una tabla InnoDB almacenada en el archivo de tabla-espacio compartido ibdata1 hace dos cosas:

  • hace que los datos de la tabla y los índices contiguos dentro ibdata1
  • Hace ibdata1 crecen porque los datos contiguos y páginas de índice son anexa aibdata1

Usted Sin embargo, puede segregar los datos de tabla y los índices de tabla desde ibdata1 y administrarlos de forma independiente.

¿Puedo ejecutar OPTIMIZE TABLE con innodb_file_per_table?

Supongamos que debe agregar innodb_file_per_table a /etc/my.cnf (my.ini). ¿Puedes ejecutar OPTIMIZE TABLE en todas las tablas de InnoDB?

Buena Nueva: Cuando se ejecuta OPTIMIZE TABLE con innodb_file_per_table habilitado, esto producirá un archivo .ibd para esa tabla. Por ejemplo, si usted tiene la tabla mydb.mytable conuna datadir de /var/lib/mysql, se producirá el siguiente:

  • /var/lib/mysql/mydb/mytable.frm
  • /var/lib/mysql/mydb/mytable.ibd

El .ibd contendrá las páginas y los datos de índice de páginas para esa tabla. Estupendo.

malas noticias: Todo lo que hemos hecho es extraer las páginas y los datos de índice de páginas de mydb.mytable de vivir en ibdata. La entrada del diccionario de datos para cada tabla, incluido mydb.mytable, permanece en el diccionario de datos (Consulte Pictorial Representation of ibdata1). NO PUEDE SIMPLEMENTE ELIMINAR ibdata1 EN ESTE PUNTO !!! Tenga en cuenta que ibdata1 no se ha reducido en absoluto.

InnoDB Infraestructura de limpieza de

a encogerse ibdata1 de una vez por todo lo que hay que hacer lo siguiente:

  1. Dump (por ejemplo,, Con mysqldump) todas las bases de datos en un archivo .sql texto (SQLData.sql se utiliza más adelante)

  2. gota todas las bases de datos (excepto para mysql y information_schema) Claves clínicas: Como medida de precaución, ejecute este script para estar absolutamente seguro de que tiene todas las concesiones de usuario en lugar de:

    mkdir /var/lib/mysql_grants 
    cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/. 
    chown -R mysql:mysql /var/lib/mysql_grants 
    
  3. Entrar a MySQL y ejecutar SET GLOBAL innodb_fast_shutdown = 0; (esto totalmente a ras todos los restantes cambios transaccionales de ib_logfile0 y ib_logfile1)

  4. apagado MySQL

  5. añadir 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: Sea cual sea su conjunto de 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. inicio de MySQL (Esto volverá a crear ibdata1 [10MB por defecto] y ib_logfile0 y ib_logfile1 a 1G cada uno).

  8. importación SQLData.sql

Ahora, ibdata1 seguirá creciendo, pero sólo contienen metadatos de la tabla, ya que cada tabla InnoDB existirá fuera de ibdata1. ibdata1 ya no contendrá datos e índices de InnoDB para otras tablas.

Por ejemplo, supongamos que tiene una tabla InnoDB llamada mydb.mytable. Si nos fijamos en /var/lib/mysql/mydb, verá dos archivos que representa la tabla:

  • mytable.frm (Cabecera motor de almacenamiento)
  • mytable.ibd (Tabla de datos e índices)

Con la opción innodb_file_per_table en /etc/my.cnf, puede ejecutar OPTIMIZE TABLE mydb.mytable y el archivo /var/lib/mysql/mydb/mytable.ibd realmente se reducirá.

Lo he hecho muchas veces en mi carrera como DBA de MySQL. De hecho, la primera vez que hice esto, reduje un archivo de 50GBibdata1 a solo 500MB!

Pruébalo. Si tiene más preguntas sobre esto, solo pregunte. Créeme; esto funcionará tanto a corto como a largo plazo.

Claves clínicas

En el paso 6, si MySQL no puede reiniciar a causa del esquema mysql begin caído, mirar hacia atrás en el paso 2. Usted ha hecho la copia física del esquema mysql. Puede restaurar 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 

Vuelva al paso 6 y continúe

ACTUALIZACIÓN 06/04/2013 11:13 EDT

Con respecto a la creación innodb_log_file_size al 25% de innodb_buffer_pool_size en El paso 5, esa es la regla general es bastante vieja escuela.

De nuevo en July 03, 2006, Percona tenía un buen artículo why to choose a proper innodb_log_file_size. Más tarde, en Nov 21, 2008, Percona siguió con otro artículo en how to calculate the proper size based on peak workload keeping one hour's worth of changes.

Desde entonces he escrito publicaciones en el DBA StackExchange acerca de cómo calcular el tamaño del registro y dónde hice referencia a esos dos artículos de Percona.

En lo personal, yo todavía ir con la regla del 25% para una configuración inicial. Luego, como la carga de trabajo puede determinarse con mayor precisión a lo largo del tiempo en producción, you could resize the logs durante un ciclo de mantenimiento en solo minutos.

+9

También he usado la opción innodb_file_per_table para gran efecto, tener 200 bases de datos con 200 tablas cada una en un solo servidor, pude enlazar las bases de datos de diferencias en diferentes particiones, por lo tanto, usar más buffers IO y spindles que de otro modo habrían estado disponibles :) –

+0

Esta es una gran solución. Nos estábamos quedando sin espacio de disco en dos de nuestras máquinas y esta solución despejó aproximadamente un tercio del disco libre. Es un proceso aterrador ya que está borrando sus bases de datos, ¡pero funciona! Incluso hemos visto un ligero aumento en el rendimiento – SeanDowney

+2

@SeanDowney Por cierto, recuerde subir 'innodb_open_tables' si es necesario. El valor predeterminado es 300. – RolandoMySQLDBA

4

El motor InnoDB no almacena datos eliminados. A medida que inserta y elimina filas, el espacio no utilizado se deja asignado dentro de los archivos de almacenamiento de InnoDB. Con el tiempo, el espacio global no disminuirá, pero con el tiempo el espacio de 'borrado y liberado' será reutilizado automáticamente por el servidor de BD.

Puede además optimizar y administrar el espacio utilizado por el motor a través de una reorganización manual de las tablas. Para hacer esto, vacíe los datos en las tablas afectadas usando mysqldump, suelte las tablas, reinicie el servicio mysql y luego vuelva a crear las tablas de los archivos de volcado.

-1

Puede utilizar la consulta OPTIMIZE TABLE periódicamente para optimizar su almacenamiento y acelerar las consultas SELECT un poco. Enlace a MySQL Manual: OPTIMIZE TABLE Syntax

Cuestiones relacionadas