¿Cuál es la mejor manera de reducir el tamaño de ibdata en mysql?


63

Tengo algunos servidores de producción cuyos ibdataarchivos aumentan de tamaño día a día.

Ya ha consumido 290 GB de espacio.

Las tablas en los servidores son principalmente InnoDB y hay muchas solicitudes de lectura y escritura.

El tamaño del archivo de registro también aumenta. Hay una gran cantidad de datos en las tablas.

¿Cómo puedo controlar el tamaño creciente de ambos?

No estoy usando innodb_file_per_table.

Respuestas:


104

Tenga en cuenta que el archivo más ocupado en la infraestructura de InnoDB es / var / lib / mysql / ibdata1

Este archivo normalmente alberga muchas clases de información (cuando innodb_file_per_table es 0)

  • Datos de tabla
  • Índices de tabla
  • Datos MVCC (Control de concurrencia multiversionante)
    • Segmentos de reversiones
    • Deshacer espacio de tabla
  • Metadatos de tabla
  • Ver representación pictórica

Muchas personas crean múltiples archivos ibdata con la esperanza de una mejor gestión y rendimiento del espacio en disco. No ayuda.

Desafortunadamente, OPTIMIZE TABLE contra una tabla InnoDB almacenada en ibdata1 hace dos cosas:

  • Hace que los datos e índices de la tabla sean contiguos dentro de ibdata1
  • Hace que ibdata1 crezca porque los datos contiguos se agregan a ibdata1

Puede segregar los datos de tabla y los índices de tabla de ibdata1 y administrarlos de forma independiente utilizando innodb_file_per_table . Para reducir ibdata1 de una vez por todas, debe hacer lo siguiente

Paso 01) MySQL Vuelca todas las bases de datos en un archivo de texto SQL (llámalo SQLData.sql) ( Más detalles aquí )

Paso 02) Descarte todas las bases de datos (excepto mysql, performance_schemay information_schema)

Paso 03) Apagar mysql

Paso 04) Agregue las siguientes líneas a /etc/my.cnf

[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 conjunto para innodb_buffer_pool_size, asegúrese de que innodb_log_file_size sea el 25% de innodb_buffer_pool_size.

Paso 05) Eliminar ibdata1, ib_logfile0 e ib_logfile1

En este punto, solo debe haber el esquema mysql en / var / lib / mysql

Paso 06) Reinicia mysql

Esto recreará ibdata1 a 10MB, ib_logfile0 e ib_logfile1 a 1G cada uno

Paso 07) Vuelva a cargar SQLData.sql en mysql

ibdata1 crecerá pero solo contendrá metadatos de tabla

Cada tabla InnoDB existirá fuera de ibdata1

Supongamos que tiene una tabla InnoDB llamada mydb.mytable. Si ingresa en / var / lib / mysql / mydb, verá dos archivos que representan la tabla

  • mytable.frm (encabezado del motor de almacenamiento)
  • mytable.ibd (Página principal de datos de tabla e índices de tabla para mydb.mytable)

ibdata1 nunca contendrá más datos e índices de InnoDB.

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

Lo he hecho muchas veces en mi carrera como DBA MySQL

De hecho, la primera vez que hice esto, colapsé un archivo ibdata1 de 50 GB en 500 MB.

Darle una oportunidad. Si tiene más preguntas sobre esto, envíeme un correo electrónico. Créeme. Esto funcionará a corto plazo y a largo plazo. !!!

Si desea ver cuántos datos reales se almacenan en MyISAM e InnoDB, ejecute esta consulta:

SELECT IFNULL(B.engine,'Total') "Storage Engine",
CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Data Size", CONCAT(LPAD(REPLACE(
FORMAT(B.ISize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Index Size", CONCAT(LPAD(REPLACE(
FORMAT(B.TSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Table Size"
FROM (SELECT engine,SUM(data_length) DSize,SUM(index_length) ISize,
SUM(data_length+index_length) TSize FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema')
AND engine IS NOT NULL GROUP BY engine WITH ROLLUP) B,
(SELECT 3 pw) A ORDER BY TSize;

Incluso con la configuración sugerida para my.cnf (que ya tengo), eliminando ib_logfile0 y 1 y luego iniciando mysql, se crean los nuevos archivos y en cuestión de segundos crecen hasta el tamaño de la base de datos como se muestra en la consulta anterior. No estoy seguro de si mysql está copiando todas las tablas e índices a estos archivos mientras mantiene cada tabla en un archivo separado.
Allen King
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.