¿Por qué usar innodb_file_per_table?

27

Hay muchos artículos que exageran (en mi humilde opinión, por supuesto) la necesidad de innodb_file_per_table. Entiendo que con innodb_file_per_table, debería haber un mejor control sobre las tablas individuales; como copia de seguridad de cada tabla por separado. Sin embargo, la afirmación de un mejor rendimiento es cuestionable.

En mi prueba, no hay diferencia en el rendimiento de innodb_file_per_tabley ibdata1para una base de datos de 60 GB. Por supuesto, fue una prueba simple con consultas normales, y la situación puede ser diferente para consultas complicadas en la vida real (esta es la razón por la que hice esta pregunta). Linux de 64 bits con ext4puede manejar efectivamente archivos grandes.

Con innodb_file_per_table, se necesitan más operaciones de E / S de disco; y esto es significativo en complicados JOINsy FOREIGN KEYrestricciones.

Tablespace se comparte en single ibdata; ¿Cómo los espacios de tabla dedicados para tablas separadas pueden ahorrar espacio en disco? Por supuesto, es más fácil liberar espacio de tabla para cada tabla ALTER, pero sigue siendo un proceso costoso (con bloqueo de tabla).

PREGUNTA: ¿ innodb_file_per_tableTiene un efecto en un mejor rendimiento de mysql? ¿Si es así por qué?

Googlebot
fuente
Consulte esta respuesta a mi pregunta: dba.stackexchange.com/questions/7924/… también podría ayudar.
KM.

Respuestas:

19

No creo que sea una cuestión de rendimiento sino de gestión.

Con un archivo separado por tabla, puede almacenar diferentes bases de datos en diferentes dispositivos de almacenamiento, por ejemplo.

Puede tratar el caso de bases de datos muy grandes en sistemas de archivos que no pueden manejar archivos grandes (al menos posponga el problema hasta que una tabla alcance el límite de tamaño de archivo).

No tienes un crecimiento incontrolado del espacio de tabla. Si tiene algunas tablas grandes que descarta, el ibdataarchivo permanece pequeño.

Un aspecto que puede tener algún efecto en el rendimiento es la fragmentación de los datos e índices de la tabla, que estará limitada por tabla. Pero eso necesita pruebas para ser confirmado.

ypercubeᵀᴹ
fuente
El crecimiento del espacio de tabla es exactamente por qué quieres innodb_file_per_table.
sjas
13

¿Por qué usar innodb_file_per_table?

Porque es más fácil de administrar individualmente, ya que se puede hacer a nivel de archivo. Esto significa que incluso si el servidor está caído, aún puede copiar datos copiando los archivos de la tabla, mientras que usar un espacio de tabla compartido significa copiar todo lo que puede ser innecesariamente masivo o encontrar alguna forma de hacer que el servidor se ejecute para extraer datos ( realmente no desea extraer manualmente los datos con un editor hexadecimal).

Alguien advirtió que no puede simplemente copiar y pegar .ibdarchivos de un servidor a otro. Esto puede ser cierto, pero no debería aplicarse a las copias de seguridad en el mismo servidor (estoy usando el término copia de seguridad aquí en el sentido tradicional de hacer una copia; es decir, no cambiar drásticamente todo el asunto). Además, ibdata1se vuelve a crear automáticamente al inicio (como se ve en el paso de eliminaciónibdata1 de la mayoría de las guías de "conversión a archivo por tabla"). Como tal, no necesita copiar ibdata1además de sus .ibdarchivos (y sus .frmarchivos correspondientes , etc.).

Si intenta recuperar una tabla perdida, debería ser suficiente copiarla .ibdy su .frmarchivo, así como information_schema(que es mucho más pequeño que ibdata1). De esa manera, puede ponerlos en un servidor ficticio y extraer su tabla sin tener que copiar todo el conjunto.

Sin embargo, la afirmación de un mejor rendimiento es cuestionable. ... Con innodb_file_per_table, se necesitan más operaciones de E / S de disco; y esto es significativo en las restricciones complicadas de JOIN y FOREIGN KEY.

No es sorprendente que el rendimiento dependa completamente de las bases de datos específicas en uso. Una persona tendrá (incluso mucho) diferentes resultados de otra.

Es cierto que habrá más operaciones de E / S de disco con archivo por tabla, pero solo un poco más. Piensa en cómo funciona el sistema.

  • Para una base de datos monolítica:

    1. El servidor se ha iniciado
    2. ibdata1 está abierto
    3. El encabezado y los metadatos se leen
    4. Las estructuras y los metadatos se almacenan en memoria caché.
    5. Las consultas suceden
      1. El servidor accede al disco y lee los datos del archivo ya abierto ibdata1
      2. El servidor puede almacenar en caché los datos en la memoria
  • Para una base de datos por tabla:

    1. El servidor se ha iniciado
    2. ibdata1 está abierto
    3. El encabezado y los metadatos se leen
    4. Cada individuo .ibd archivo se abre
    5. El encabezado y los metadatos se leen de cada .ibd archivo
    6. Las estructuras y los metadatos se almacenan en memoria caché.
    7. Las consultas suceden
      1. El servidor accede al disco y lee los datos del archivo ya abierto .ibd archivo
      2. El servidor puede almacenar en caché los datos en la memoria

Notará que cuando el servidor se está ejecutando, no puede mover los archivos de datos porque el servidor tiene identificadores abiertos para ellos. Esto se debe a que cuando se inicia, los abre y los deja abiertos. No los abre ni los cierra para cada consulta individual.

Como tal, solo hay algunas operaciones de E / S más al principio, cuando se inicia el servidor; No mientras se está ejecutando. Además, aunque cada .ibdarchivo individual tiene su propia sobrecarga separada (firmas de archivo, estructuras, etc.), se almacenan en la memoria caché y no se vuelven a leer para cada consulta. Además, las mismas estructuras se leen incluso con un espacio de tabla compartido, por lo que apenas se necesita (si es que hay alguna) más memoria.

¿Innodb_file_per_table tiene un efecto en un mejor rendimiento de mysql?

En realidad, en todo caso, el rendimiento puede ser peor .

Cuando se utiliza un espacio de tabla compartido, las operaciones de lectura y escritura a veces / a menudo se pueden combinar para que el servidor lea una muestra de datos de varias tablas de una sola vez. ibdata .

Sin embargo, si los datos se distribuyen entre varios archivos, entonces debe realizar una operación de E / S por separado para cada uno.

Por supuesto, esto depende nuevamente de la base de datos en cuestión; El impacto en el rendimiento del mundo real dependerá del tamaño, la frecuencia de las consultas y la fragmentación interna del espacio de tabla compartido. Algunas personas pueden notar una gran diferencia, mientras que otras pueden no ver ningún impacto en absoluto.

Tablespace se comparte en ibdata individual; ¿Cómo los espacios de tabla dedicados para tablas separadas pueden ahorrar espacio en disco?

No es asi. En todo caso, aumenta un poco el uso del disco.

No tengo una base de datos de 60 GB para probar, pero mi base de datos personal "miserable" que contiene mi instalación de WordPress y algunas tablas pequeñas para uso personal y pruebas de desarrollo pesaron ~ 30 MB mientras usaba un espacio de tabla compartido. Después de convertirlo a archivo por tabla, se hinchó a ~ 85 MB. Incluso al soltar todo y volver a importar, todavía era> 60 MB.

Este aumento se debe a dos factores:

  • El tamaño mínimo absoluto para ibdata1es, por alguna razón, 10 MB, incluso si no tiene nada más que information_schemaalmacenado en él.

  • Con un espacio de tabla compartido, solo ibdata1tiene gastos generales como firmas de archivo, metadatos, etc., pero con cada tabla, cada .ibdarchivo individual tiene todo eso. Esto significa que el total (incluso con un hipotético <10 MB ibdata1) sería algo mayor al menos:

    GetTotalSizeofOverhead() * GetNumTables()

Obviamente, estos no van a ser grandes aumentos (a menos que esté utilizando un host que limite el tamaño de su base de datos o los almacene en una unidad flash, etc.), pero de todos modos son aumentos, y al cambiar ( cada ) tabla a archivo -por tabla puede reducirse ibdata1a 10 MB, el total general invariablemente será más de lo que era.

Synetech
fuente
11

Esta es mi razón para SIEMPRE usar innodb_file_per_table:

Sin archivo por tabla, el archivo ibdata nunca se comprime, encoge o disminuye en el espacio. No cuando elimina una fila, suelta una tabla o una base de datos. 2 GB de datos pueden convertirse en un archivo de 20 GB en poco tiempo si tiene un sistema de colas activo.

Supongamos que desea hacer una copia de seguridad de su tabla actual de 1GB antes de una modificación, luego suéltela. Estás atrapado con un GB de espacio ahora no utilizado en tu ibdata. Gorrón.

Probablemente hay un sinfín de ejemplos de casos en los que las medidas temporales inflan el archivo de datos único, pero es suficiente decir que, en mi opinión, nunca hay una razón para NO usar innodb_file_per_table

Además, aquí hay una buena publicación para leer: http://code.openark.org/blog/mysql/reasons-to-use-innodb_file_per_table

randomx
fuente
1
Me di cuenta de que siempre es bueno hacerlo también. Las matrices de almacenamiento magnético respaldadas por SSD pueden manejar cachés de lectura / escritura de manera más efectiva contra archivos más pequeños para tablas. Para un montón de tablas que% 99.99 de las veces solo se 'leen' pero no se escriben, siempre están en la memoria caché del controlador de almacenamiento, lo que es una gran reducción en el tiempo de respuesta.
sdkks el
5

Mi razón por la que no usar innodb_file_per_table es el rendimiento.

Hice algunas pruebas para nuestra base de datos con 450 tablas en mysql 5.5.45 Linux CentOS versión 6.7

Para las pruebas unitarias que insertan elementos fijos en la base de datos antes de cada prueba (no usa todas las tablas cada vez) y también las pruebas en sí mismas funcionan mucho con la base de datos (inserta, actualiza, elimina, selecciona) el rendimiento fue 3-5 veces mejor cuando las tablas de la base de datos no estaban separados en más archivos.

Recomiendo probar su base de datos con las consultas que desea usar y compararlas antes de decidir usar innodb_file_per_table

Tal vez pueda descubrir que para el servidor de producción puede usar innodb_file_per_table pero para el entorno CI (integración continua) que comienza las pruebas unitarias (usa mucho DB) y también los desarrolladores que comienzan muchas pruebas unitarias es mejor no usarlo debido al rendimiento.

Tomor
fuente
2
Supongo que esto se debe al tiempo requerido para asignar los archivos iniciales para las 450 tablas en lugar de asignar un solo archivo. En producción, esto solo sucederá una vez, por lo que no debería ser un problema, pero es importante señalar que crear una base de datos rápidamente y luego destruirla por completo y repetir una y otra vez un solo archivo ibdata es mejor.
ColinM 01 de
2

Hace que los datos sean más manejables porque puede reclamar espacio no utilizado, lo cual es bueno.

Creo que si su base de datos se usa principalmente para consultas seleccionadas, no afectará mucho el rendimiento. Todavía tiene que leer sobre la misma cantidad de datos. No creo que importe mucho de qué archivos está leyendo los datos.

Sin embargo, puede empeorar el rendimiento en una base de datos que realiza muchas inserciones y actualizaciones. Esto se debe a que mysql llama a fsync () en el archivo de almacenamiento después de confirmar una transacción. Si hay un solo archivo, realiza una llamada y espera a que se complete la llamada. Si hay muchos archivos, debe realizar la llamada varias veces y esperar a que todas esas llamadas regresen antes de que el comando commit pueda regresar.

Aquí hay una publicación de alguien que experimentó este problema: http://umangg.blogspot.com/2010/02/innodbfilepertable.html

Sarel Botha
fuente
2

Según el artículo a continuación, el rendimiento no se trata de administrar datos (operaciones crudas en sí) sino de crear y soltar objetos.

innodb_file_per_table hace que la creación masiva y la caída de objetos sean más lentas que el almacenamiento de ibdata y para la producción no es aplicable, pero para la prueba continua debería ser relevante.

https://www.percona.com/blog/2015/02/24/mysqls-innodb_file_per_table-slowing/

Flavio Peinado
fuente