Resumen de varios esquemas de desfragmentación para MySQL (para solucionar el problema de no liberar espacio después de borrar una gran cantidad de datos)

Resumen de varios esquemas de desfragmentación para MySQL (para solucionar el problema de no liberar espacio después de borrar una gran cantidad de datos)

1. ¿Conocimiento previo?

1.1 ¿Por qué hay fragmentos?

  1. Tanto la inserción como la actualización en MySQL pueden provocar la división de la página, por lo que existe fragmentación.

    Para una gran cantidad de ACTUALIZACIONES, también se producirá la fragmentación de archivos. La unidad mínima de asignación de almacenamiento físico de Innodb es una página (página), y las ACTUALIZACIONES también pueden causar divisiones de página. Las divisiones de página frecuentes harán que las páginas se dispersen y se eliminen. Relleno irregular, por lo que los datos finales se fragmentarán.

  2. La declaración de eliminación en realidad solo marca los datos y los registra en una lista enlazada, formando así un espacio en blanco.

    En InnoDB, elimine algunas filas, estas filas simplemente se marcan como "eliminadas", pero no se eliminan físicamente del índice, por lo que el espacio no se libera ni se reclama realmente. El subproceso de purga de InnoDB limpiará de forma asincrónica estas filas y claves de índice inútiles.

  3. Al realizar una operación de inserción, MySQL intentará usar un espacio en blanco, pero si un cierto espacio en blanco no ha sido ocupado por datos de un tamaño adecuado, aún no puede ocuparse por completo y se forma una fragmentación;

  4. Resumir:

    1. Las operaciones de adición, eliminación y modificación de tablas pueden causar lagunas de datos.Cuando se realiza una gran cantidad de operaciones de adición, eliminación y modificación en una tabla, es más probable que existan lagunas de datos.

    2. Varias situaciones en las que MySQL elimina datos y si liberar espacio en disco:

      1. soltar, truncar inmediatamente liberar espacio en disco, ya sea Innodb o MyISAM;
      • Truncar la tabla es en realidad un poco similar a soltar la tabla y luego crearla, pero el proceso de creación de la tabla se ha optimizado, por ejemplo, el archivo de estructura de la tabla ya existe, etc. Entonces, la velocidad debe estar cerca de la velocidad de la mesa de caída;
      1. delete from table_name elimina todos los datos en la tabla.Para MyISAM, el espacio en disco se liberará inmediatamente (debe ser especialmente procesado, lo cual es más razonable), e InnoDB no liberará el espacio en disco;
      2. Para eliminar de table_name donde xxx, eliminación condicional, ni innodb ni MyISAM liberarán espacio en disco;
      3. El uso de la tabla de optimización table_name después de la operación de eliminación liberará espacio en disco inmediatamente. No importa innodb o myisam. Por lo tanto, para lograr el objetivo de liberar espacio en disco, realice la operación de optimización de la tabla después de la eliminación.
      4. Aunque el espacio en disco no se libera después de la eliminación de la tabla, este espacio aún se puede utilizar al insertar datos la próxima vez.

1.2 Problemas causados ​​por la fragmentación

  • Cuando MySQL escanea los datos, el objeto que escanea es en realidad el límite superior del requisito de capacidad de la lista, es decir, la parte en la posición máxima en el área donde se escriben los datos;

  • Después de realizar varias eliminaciones, actualizaciones e inserciones en las tablas de la base de datos MySQL, el espacio de la tabla se fragmentará. La desfragmentación regular del espacio de tablas puede mejorar el rendimiento del acceso al espacio de tablas al eliminar la fragmentación.

  • Este tipo de fragmentación no solo aumenta el costo de almacenamiento, sino que también reduce la eficiencia de escaneo de la tabla debido a la fragmentación de datos.

  • Si no se desfragmenta, puede ocupar espacio en disco durante mucho tiempo, lo que genera un uso cada vez mayor del disco.

2. ¿Cómo limpiar los escombros?

La premisa para solucionar el problema es encontrar el problema primero, para prescribir el medicamento adecuado.

2.1 Ver la fragmentación de la tabla

  1. Ver cada tabla fragmentada en la base de datos

    mysql> select concat('optimize table ',table_schema,'.',table_name,';'),data_free,engine from information_schema.tables where data_free>0 and engine !='MEMORY';
    +-----------------------------------------------------------+-----------+--------+
    | concat('optimize table ',table_schema,'.',table_name,';') | DATA_FREE | ENGINE |
    +-----------------------------------------------------------+-----------+--------+
    | optimize table abc.t_user_answer;                    		|   2097152 | InnoDB |
    | optimize table mysql.time_zone_transition;                |   4194304 | InnoDB |
    | optimize table mysql.time_zone_transition_type;           |   4194304 | InnoDB |
    | optimize table mysql.user;                                |   4194304 | InnoDB |
    。。。。
    
  2. Ver la fragmentación de la tabla especificada

     mysql> show table status like 't_user'\G
     *************************** 1. row ***************************
                Name: t_user
              Engine: InnoDB
             Version: 10
          Row_format: Dynamic
                Rows: 4333
      Avg_row_length: 589
         Data_length: 2555904
     Max_data_length: 0
        Index_length: 2719744
           Data_free: 4194304
      Auto_increment: NULL
         Create_time: 2021-11-19 10:13:31
         Update_time: 2022-04-20 14:28:42
          Check_time: NULL
           Collation: utf8mb4_general_ci
            Checksum: NULL
      Create_options:
             Comment:
     1 row in set (0.00 sec)
    

    Data_free: 4194304 representa el número de bytes de fragmentos. Si la tabla de datos se elimina con frecuencia, provocará que una gran cantidad de Data_free elimine registros con frecuencia o modifique tablas con campos de longitud variable.

  3. Encuentra la tabla más fragmentada

    SELECT table_schema, TABLE_NAME, concat(data_free/1024/1024, 'M') as data_free
    FROM `information_schema`.tables
    WHERE data_free > 3 * 1024 * 1024
    	AND ENGINE = 'innodb'
    ORDER BY data_free DESC
    

2.2 Métodos de limpieza de escombros (recuperación de espacio)

Referencia de documentación oficial
inserte la descripción de la imagen aquí

Por lo general, hay varias formas

  1. alterar la tabla tb_test engine=innodb; (esencialmente recrear)
  2. optimizar la tabla tb_test; (esencialmente recrear, pero habrá diferencias en diferentes creaciones)
  3. ALTER TABLE tablename FORCE ( equivalente a alter table tb_test engine=innodb; en tablas InnoDB )
  4. optimización del espacio de tablas por lotes de mysqlcheck
  5. gh-ost/pt-osc
  6. pt-online-schema-change (esencialmente, haga una copia de seguridad de los datos de la tabla anterior primero, luego trunque la tabla anterior)

1. alter table tb_test engine=introducción del principio innodb

Esta es en realidad una operación NULL, que no hace nada en la superficie, pero en realidad reorganiza los fragmentos. Al realizar una operación de optimización, lo que realmente se ejecuta es un comando ALTER vacío, pero este comando también desempeñará un papel de optimización, reconstruirá el toda la tabla, eliminando el espacio vacío no utilizado.

Ejecutar ALTER TABLE tbl_name ENGINE=INNODB en una tabla InnoDB existente realiza una operación ALTER TABLE "nula", que se puede usar para desfragmentar una tabla InnoDB, como se describe en la Sección 15.11.4, "Desfragmentación de una tabla". Ejecutar ALTER TABLE tbl_name FORCE en una tabla InnoDB realiza la misma función.

    MySQL5.6 开始采用 Inplace 方式重建表,Alter 期间,支持 DML 查询和更新操作,语句为 alter table t engine=innodb, ALGORITHM=inplace;之所以支持 DML 更新操作,是因为数据拷贝期间会将 DML 更新操作记录到 Row log 中。

    重建过程中最耗时的就是拷贝数据的过程,这个过程中支持 DML 查询和更新操作,对于整个 DDL 来说,锁时间很短,就可以近似认为是 Online DDL。

    执行过程:

    1、获取 MDL(Meta Data Lock)写锁,innodb 内部创建与原表结构相同的临时文件

    2、拷贝数据之前,MDL 写锁退化成 MDL 读锁,支持 DML 更新操作

    3、根据主键递增顺序,将一行一行的数据读出并写入到临时文件,直至全部写入完成。并且,会将拷贝期间的 DML 更新操作记录到 Row log 中

    4、上锁,再将 Row log 中的数据应用到临时文件

    5、互换原表和临时表表名

    6、删除临时表

2. optimizar tabla xxx;

La instrucción OPTIMIZE TABLE puede reorganizar el almacenamiento físico de tablas e índices, reducir el espacio de almacenamiento y mejorar la eficiencia de E/S de acceso. Similar a la función de desfragmentación.

MySQL puede liberar el espacio de la tabla a través de optimize tabledeclaraciones, reorganizar las páginas físicas de los datos de la tabla y los índices, reducir el espacio ocupado por la tabla y optimizar el rendimiento de lectura y escritura.

  1. usar sintaxis

    OPTIMIZAR [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] …

    • Para la arquitectura maestro-esclavo, el parámetro LOCAL puede evitar que este proceso se escriba en el binlog, de modo que no se sincronizará con la biblioteca esclava cuando se ejecute en la biblioteca maestra.
    • De forma predeterminada, MySQL escribe instrucciones OPTIMIZE TABLE en el registro binario para que se repliquen en servidores esclavos. Si no desea escribir el registro binario, puede agregar la palabra clave NO_WRITE_To_BINLOG o LOCAL al usar el comando.
    • El uso de esta declaración requiere permisos SELECT e INSERT en la tabla de destino.
  2. Aviso:

    1. Se requiere espacio suficiente para OPTIMIZE TABLE. (El espacio restante debe ser > el tamaño de la tabla OPTIMIZE)

    2. OPTIMIZE solo es útil para espacios de tablas independientes (innodb_file_per_table=1), no para espacios de tablas compartidos.

      Para el espacio de tablas compartido, si necesita reducirlo: debe exportar los datos, eliminar ibdata1, luego configurar innodb_file_per_table como un espacio de tablas independiente y luego importar los datos.

    3. Para tablas InnoDB , OPTIMIZE TABLE funciona de la siguiente manera

      Para tablas InnoDB, OPTIMIZE TABLE se asigna a ALTER TABLE ... FORCE (o traducido de esta manera: equivalente ALTER TABLE ... FORCE en tablas InnoDB), que reconstruye la tabla para actualizar las estadísticas del índice y liberar espacio no utilizado en el índice agrupado.

      当您在InnoDB表上运行时,它会显示在OPTIMIZE TABLE的输出中,如下所示:
      mysql> OPTIMIZE TABLE foo; 
      +----------+----------+----------+---------------------------------------+ 
      | Table    | Op       | Msg_type | Msg_text                                                          | 
      +----------+----------+----------+---------------------------------------+ 
      | test.foo | optimize | note     | Table does not support optimize, doing recreate + analyze instead | 
      | test.foo | optimize | status   | OK                                                                | 
      +----------+----------+----------+---------------------------------------+ 
      
      # 但这个提示语可以忽略,从严格的意义讲,说InnoDB不支持optimize table,其实不太准确。 因为 MYSQL的文档说明了,当INNODB 的表,MYSQL会以 ALTER TABLE force  +  analyze 去执行这个命令(相当于做了recreate和analyze)。 所以最终还是会看到 OK 的状态。 
      # https://stackoverflow.com/questions/30635603/what-does-table-does-not-support-optimize-doing-recreate-analyze-instead-me
      
    4. Para las tablas MYISAM , OPTIMIZE TABLE funciona:
      1. Si la tabla ha eliminado o separado filas, repárela.
      2. Si las páginas de índice no están ordenadas, ordénelas.
      3. Si las estadísticas de la tabla no están actualizadas (y la reparación no se puede realizar ordenando los índices), actualícelas.

    5. **También se puede encontrar un error durante la ejecución: error de escritura del archivo temporal.**

      Se recomienda consultar este artículo:
      La tabla de optimización de Mysql informa de un error Fallo temporal de escritura del archivo.

  3. El sitio web oficial de introducción de la declaración de optimización

    • Debe usar OPTIMIZE TABLE si ha eliminado una gran parte de la tabla o si ha realizado muchos cambios en una tabla con filas de longitud variable (tablas con columnas VARCHAR, BLOB o TEXT).

    • Los registros eliminados se mantienen en una lista vinculada y las operaciones INSERT posteriores reutilizarán la ubicación del registro anterior. Puede usar OPTIMIZE TABLE para reutilizar el espacio no utilizado y desfragmentar archivos de datos.

    • En la mayoría de las configuraciones, no necesita ejecutar OPTIMIZE TABLE en absoluto. Incluso si realiza muchas actualizaciones en las filas de longitud variable, no necesita ejecutarlas muy a menudo, semanal o mensualmente, solo para tablas específicas.

  4. Antes de Mysql 5.6, MySQL bloqueaba la tabla durante la operación de OPTIMIZE TABLE.Después de 5.6, con Online DDL, el tiempo de bloqueo de la tabla se reduce considerablemente.

3. La diferencia entre modificar tabla, analizar tabla y optimizar tabla

  • modificar tabla tb_test motor = innodb;

    • (Es decir, recrear) Antes de MySQL 5.5, las tablas se reconstruían en modo sin conexión, y después de 5.6, las tablas se reconstruían en modo en línea;
  • analizar tabla tb_test;

    • La información de índice de la tabla se reafirma, los datos no se modificarán, la tabla no se reconstruirá y MDL leerá todo el proceso
  • optimizar la tabla tb_test;

    • Es el proceso de alterar tabla xxx = innodb;+analizar tabla xxx;.

4. ¿Qué es mejor, OPTIMIZE TABLE o ALTER TABLE xxxx ENGINE= INNODB?

  • OPTIMIZE TABLE o ALTER TABLE xxxx ENGINE= INNODB es básicamente lo mismo. Pero en algunos casos, ALTER TABLE xxxx ENGINE= INNODB es mejor.
    • Por ejemplo: la variable de sistema old_alter_table no está habilitada, etc.
  • Además: Para tablas tipo MyISAM, usar ALTER TABLE xxxx ENGINE= INNODB es obviamente mejor que OPTIMIZE TABLE.

2.3 Recomendaciones oficiales

MySQL recomienda oficialmente no desfragmentar con frecuencia (por hora o por día). Generalmente, de acuerdo con la situación real, solo necesita ser desfragmentado una vez a la semana o al mes (ahora estamos limpiando los fragmentos de la tabla en todas las instancias de mysql a las 4:00 a. m. todos los meses)

Supongo que te gusta

Origin blog.csdn.net/UserFrank/article/details/124711275
Recomendado
Clasificación