MySQL InnoDB - innodb_file_per_table contras?

32

Por defecto, MySQL InnoDB almacena todas las tablas de todos los DB en un archivo global. Puede cambiar esto configurando innodb_file_per_table en la configuración, que luego crea un archivo de datos para cada tabla.

Me pregunto por qué innodb_file_per_tableno está habilitado de forma predeterminada. ¿Hay inconvenientes para usarlo?

Hasta el arroyo
fuente

Respuestas:

32

Tengo la respuesta completa para esta.

Una vez que innodb_file_per_table se establece, y las nuevas tablas de InnoDB se pueden ALTER TABLE <innodb-table-name> ENGINE=InnoDB';reducir utilizando Esto reducirá los .ibdarchivos nuevos GARANTIZADOS.

Si ejecuta ALTER TABLE <innodb-table-name> ENGINE=InnoDB';una tabla InnoDB creada antes de usar innodb_file_per_table, extraerá los datos e índices de esa tabla del archivo ibdata1 y la almacenará en un .ibdarchivo. Esto dejará una paloma permanente entera en ibdata1 que nunca podrá reutilizarse. .

El ibdata1archivo normalmente alberga cuatro tipos de información.

  • Datos de tabla
  • Índices de tabla
  • Datos MVCC (Control de concurrencia multiversionante)
    • Segmentos de reversión
    • Deshacer espacio
  • Metadatos de tabla (Diccionario de datos)
  • Memoria intermedia de doble escritura (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)
  • Ver el Pictorial Representation of ibdata1

Aquí está la forma garantizada de reducir el archivo ibdata1 casi para siempre ...

PASO 01) MySQL Vuelca todas las bases de datos en un archivo de texto SQL (llámalo SQLData.sql)

PASO 02) Descarte todas las bases de datos (excepto los esquemas mysql, information_schema y performance_schema)

PASO 03) Apague 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
innodb_data_file_path=ibdata1:10M:autoextend

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) Elimine ibdata1, ib_logfile0 e ib_logfile1 ( consulte la actualización a continuación antes de eliminar )

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

  • PASO 06) Reinicie mysql

Esto recreará ibdata1 a 10MB (no configure la opción), 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 y datos MVCC intermitentes.

Cada tabla InnoDB existirá fuera de ibdata1

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

  • mytable.frm (Encabezado del motor de almacenamiento)
  • mytable.ibd(Inicio 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/etc/my.cnf , puede ejecutar OPTIMIZE TABLE mydb.mytableOR ALTER TABLE mydb.mytable ENGINE=InnoDB;y el archivo /var/lib/mysql/mydb/mytable.ibdse reducirá.

Lo he hecho varias veces en mi carrera como DBA MySQL sin tener ni un solo problema a partir de entonces. De hecho, la primera vez que hice esto, colapsé un archivo ibdata1 de 50 GB en 50 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.

ACTUALIZACIÓN 2013-07-02 15:08 EDT

Hay una advertencia que tengo al respecto que actualicé en otras publicaciones mías, pero me perdí esto: estoy actualizando mi respuesta un poco más con innodb_fast_shutdown porque solía reiniciar mysql y detener mysql para hacer esto. Ahora, este paso es vital porque cada transacción no comprometida puede tener otras partes móviles dentro y fuera de los InnoDB Transaction Logs ( Ver Infraestructura InnoDB ).

Tenga en cuenta que establecer innodb_fast_shutdown en 2 también eliminaría los registros, pero aún existen más partes móviles y se selecciona en Crash Recovery durante el inicio de mysqld. La configuración de 0 es la mejor.

RolandoMySQLDBA
fuente
Gran información - gracias! 50GB >> 50MB - ¡eso es bastante impresionante!
UpTheCreek
Hola, he intentado hacer exactamente lo que escribiste aquí, el "único" problema es que el servidor no se inicia después. si hago el servicio mysql start, simplemente se cuelga allí. Si cambio mi antiguo archivo cnf, todo está bien. ¿Tienes alguna pista sobre esto?
Nicola Peluchetti
Esta pregunta es para Nicola: ¿Hiciste el Paso 5?
RolandoMySQLDBA
Otra pregunta para @Nicola: ¿Cuánta RAM tienes en tu sistema?
RolandoMySQLDBA
2
¡Ten cuidado! ¡La opción innodb_fast_shutdown=0debe configurarse en MySQL, antes de apagarla para eliminar los archivos de registro! ( ib_logfile0y ib_logfile1) De lo contrario, ¡podría perder datos!
Totor
12

Ver insecto .

¿Hay inconvenientes para usarlo?

  • más archivos abiertos
  • abrir / reabrir sobrecarga
  • El archivo .ibd no se contrae (ver 1 , 2 )

Siempre uso innodb_file_per_table en grandes bases de datos.

alvosu
fuente
Incluso si no lo usa, los archivos ibdata tampoco se reducirán :(
minaev
1
Gracias. También me pregunto por qué no hay una opción para tener un archivo por db.
UpTheCreek
1
@UpTheCreek, las tablas son entidades. Las bases de datos son grupos lógicos de entidades, en lugar de entidades por derecho propio. Es más obvio con MyISAM, donde las bases de datos son directorios y las tablas son archivos.
John Gardeniers
Solo quería señalar que, si bien los archivos .ibd no se reducen automáticamente , tampoco lo hace ibdata1, la alternativa al archivo por tabla. Al menos es posible reducir un .ibd usando optimize table, lo cual es trivial en comparación con la reducción de ibdata1.
RomanSt
8

innodb_file_per_table está habilitado por defecto en MariaDB.

Alex
fuente
1
No en la mía (la versión predeterminada en CentOS 7). Necesita el equivalente de MySQL 5.6.6 o posterior. De lo contrario, el valor predeterminado es desactivado .
Lightness compite con Monica el
2

La razón por la que opté por no usar innodb_file_per_table, es porque cada tabla se coloca en su propio archivo, lo que significa que cada tabla tiene su propia sobrecarga separada (firmas de archivo, etc.) que hace que el tamaño total del MySQLdirectorio sea total. más grande que si usa un espacio de tabla compartido. Además, hay más espacio desperdiciado debido a la holgura del clúster cuando se tienen múltiples archivos pequeños en lugar de uno solo y grande.

De acuerdo, la sobrecarga adicional no es una cantidad masiva en el gran esquema de las cosas, especialmente si está utilizando una unidad de disco grande o tiene una base de datos gigante, pero para mí (y probablemente para muchos "usuarios domésticos"), todo se suma y Todavía era demasiado para el pequeño disco con grandes grupos donde guardaba mi tienda MySQL.

Por ejemplo, mi tienda de bases de datos con mis bases de datos de WordPress y algunas otras bases de datos pequeñas (phpBB, dev, algunas pruebas de AMP, etc.), la conversión a por tabla lo cambió de 32 MB a 50 MB, y eso ni siquiera incluye el ibdata1que todavía requiere un mínimo de 10 MB , para un total de al menos 60 MB .

Como dije, esto puede no ser un gran problema para algunas personas, especialmente para las empresas, pero si usted es un usuario doméstico que solo aloja su sitio, blog, etc., entonces puede ser un factor en cosas como elegir un proveedor de host porque muchos hosts limitan el tamaño de su base de datos además del uso total del disco.

Synetech
fuente
1
Estaba pensando que estabas loco (¿a quién le importan unos diez megabytes? Nunca hubiera pensado en eso.
Dan Pritts
@DanPritts, especialmente los hosts gratuitos. Además, es posible que tenga un disco gigante, pero no todos lo hacen. He expandido mi partición de datos principal de 1GB a 2GB en el último año porque era demasiado ajustada, pero incluso 10MB aquí y 10MB allá (especialmente con archivos de registro) pueden consumirlo rápidamente. Además, no olvide que también se acumulan residuos de clúster. Finalmente, ni siquiera es necesariamente un disco duro . Por ejemplo, actualmente estoy "portablizando" mi sitio web para poder alojarlo desde cualquier sistema, por lo que una unidad flash de 2GB ya es limitada. Por lo tanto, mantener tamaños pequeños y evitar escrituras es fundamental. ¡Y luego están los sistemas integrados!
Synetech
Además, no son 10 MB (ese es el tamaño mínimo absoluto para IBDATA1). Pasó de 30MB a ~ 85MB. Al eliminar todo e importar un volcado desde cero, terminé con 69 MB en lugar de los 30 MB anteriores (una conjetura qué base de datos ocupó más de la mitad ☺). Por alguna razón, a pesar de usar por tabla, mi ibdata1todavía tiene 18 MB. ☹
Synetech
Suena como algo que tuve con una instalación de CMS con vs. uno sin selinux habilitado, a juzgar por los tamaños de archivo de 32M vs. 50M. Realmente no puedo creer los números, ¿cuántas bases de datos tienes que los metadatos de algunos archivos pueden sumar MEGABYTES en sistemas idénticos?
sjas
2

Solo para agregar un poco más de información

Desde mysql 5.6.6 está habilitado por defecto

PerroVerd
fuente