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

¿Por qué InnoDB proporciona información de espacio libre obviamente falsa?

(Esta es la respuesta a algunas de las preguntas ocultas en los comentarios).

Nombre inapropiado El espacio "libre" solo incluye bloques completos, no espacio libre dentro de los bloques y muchos otros detalles.

Caso 1:Todas las tablas están en ibdata1 -- SHOW TABLE STATUS (o la consulta equivalente en information_schema mostrará el mismo Data_free valor, es decir, cuánto es gratis en ibdata1 . Este espacio puede ser reutilizado por cualquier mesa. Es difícil devolver el espacio al sistema operativo.

Caso 2:Todas las tablas son file_per_table -- Ahora cada Data_free se refiere al espacio para la mesa. Y el SUM() es significativo (ibdata1 aún existe, pero no contiene ninguna tabla real; hay muchas otras cosas que InnoDB necesita).

Caso 3:Mezcla -- Si activa o desactiva file_per_table varias veces, algunas tablas estarán en ibdata1, otras tendrán sus propios tablespaces.

Caso 4:CREAR TABLESPACE en 5.7 -- Por ejemplo, puede tener un tablespace para cada base de datos.

Caso 5:tablas PARTICIONADAS -- Cada partición actúa como una tabla.

Caso 6:8.0 -- Se avecinan aún más cambios.

Base de datos ==Directorio En el árbol de directorios de MySQL, cada base de datos se puede ver como un directorio del sistema de archivos. Dentro de ese directorio se puede ver un conjunto de archivos para cada tabla. El .frm El archivo contiene la definición de la tabla. Si un .ibd archivo existe, la tabla se creó con file_per_table. Esta puede ser la forma más confiable de descubrir si la tabla es file_per_table. (8.0 tendrá cambios significativos aquí.)

Cuánto espacio puedo reutilizar ? No hay una buena respuesta. Por lo general, insertar una fila encontrará espacio en el bloque al que pertenece, y Data_free no se reducirá. Pero, si hubiera divisiones de bloques, Data_free puede disminuir en un múltiplo de 16 KB (el tamaño del bloque) o 4 MB (el "tamaño de la extensión", ¿o tal vez sea 8 MB?). Además, las inserciones aleatorias hacen que los bloques BTree estén, en promedio, llenos en un 69 %.

Cambiando innodb_file_per_table no tiene efecto hasta el próximo CREATE TABLE o ALTER TABLE . Y luego solo tiene efecto sobre dónde colocar los datos+índices recién creados/copiados (ibdata1 o .ibd). No destruirá datos.

Mesas grandes normalmente tienen de 4 MB a 7 MB de Data_free. Cuando calcule cuántas filas puede agregar, no planee que Data_free caiga por debajo de ese rango.

Tamaño_promedio_fila debería ser útil Pero a veces (y Filas) se aproximan mal. Su producto (Data_length) siempre es correcto. Entonces, esto podría ser una buena estimación de "filas por recorrer antes de obtener más espacio del sistema operativo:

(Data_free - 7M) / Avg_row_size

Recomendaciones de tablespaces :Coloque tablas 'grandes' en file_per_table. Coloque tablas 'pequeñas' en ibdata1 o espacios de tablas específicos de la base de datos (5.7). Lo siento, no hay una recomendación simple sobre la línea divisoria entre 'grande' y 'pequeño'. Y es torpe migrar una tabla:SET global innodb_file_per_table = ...;; cerrar sesión; iniciar sesión (para recoger el global); ALTER TABLE tbl ENGINE=InnoDB; . Y es necesariamente una copia completa de la tabla.

(Advertencia :He omitido muchos detalles.)