Entumecido, una operación colapsó por completo la replicación maestro-esclavo de MySQL

prefacio

Recientemente, un proyecto de la empresa reportó que la replicación maestro-esclavo de mysql falló, y fue registrado como un error mayor por parte del departamento de operación y mantenimiento, lo que afectó la aceptación del proyecto, entonces ¿cuál fue la causa? ¿Y cuál es el principio de replicación maestro-esclavo? Este artículo hace un registro del proceso de investigación y análisis.

Principio de replicación maestro-esclavo

Primero comprendamos brevemente el principio de la replicación maestro-esclavo de MySQL.

  1. El servidor de la biblioteca principal masterescribirá registros SQL en el registro binario a través de dumpsubprocesos binary log;
  2. slaveAbra un io threadhilo desde el servidor de la biblioteca para enviar una solicitud al servidor y masteruna solicitud a la biblioteca principal binary log. Después de que el masterservidor de la biblioteca principal reciba la solicitud, binary logenviará al slaveservidor de acuerdo con el desplazamiento.
  3. Después deslave recibir una nueva del servidor de la biblioteca , se escribe en su propio registro , que es el llamado registro de retransmisión.binary logrelay log
  4. Desde el slaveservidor de la biblioteca, después de abrir una sql threadlectura relay log, escríbala en sus propios datos, para garantizar la coherencia de los datos maestro-esclavo.

Lo anterior es un breve principio de la replicación maestro-esclavo de MySQL, y no se discutirán más detalles.De acuerdo con los comentarios de operación y mantenimiento, la falla de la replicación maestro-esclavo se debe principalmente al tiempo de espera del subproceso IO para obtener el binario log. Es normal ver que el registro de la base de datos maestra ha llegado a bin log4G binlog. Bajo las circunstancias, de acuerdo con la configuración, no debe exceder los 300M.

mecanismo de escritura binlog

Para entender binlogpor qué llega a 4G, echemos un vistazo al mecanismo de escritura binlog.

binlogEl tiempo de escritura también es muy simple.Durante la ejecución de la transacción, el registro se escribe primero binlog cache, y cuando se confirma la transacción, se binlog cacheescribe binlogen el archivo. Debido a que una transacción binlogno se puede desensamblar, no importa cuán grande sea la transacción, debe escribirse de una sola vez, por lo que el sistema asignará un bloque de memoria para cada subproceso binlog cache.

  1. La figura anterior writese refiere a escribir el registro en el sistema de archivos page cachey no conserva los datos en el disco, por lo que la velocidad es relativamente rápida.
  2. La figura anterior fsynces la operación de persistir datos en el disco y generar binlogregistros

En producción, binlogla configuración en MySQL max_binlog_sizees 250M, max_binlog_sizepero se usa para controlar el tamaño de un solo registro binario. Cuando el tamaño del archivo de registro actual supera esta variable, se ejecutará la acción de cambio. , esta configuración no puede controlar estrictamente el tamaño del Binlog, especialmente binlogcuando está cerca del valor máximo y se encuentra con una transacción relativamente grande, para garantizar la integridad de la transacción, es posible que no se realice la acción de cambiar registros, y todos $ QL se registra en el registro actual hasta el final de la transacción. En general, se puede adoptar el valor predeterminado.

Entonces dudamos si hemos encontrado una transacción grande, por lo que necesitamos ver qué transacción causó el contenido en el binlog.

Ver registros binlog

Podemos usar mysqlbinlogesta herramienta para ver el contenido en el binlog. Para un uso específico, consulte el sitio web oficial: https://dev.mysql.com/doc/refman/8.0/en/mysqlbinlog.html.

  1. ver binlogregistro
./mysqlbinlog --no-defaults --base64-output=decode-rows -vv /mysqldata/mysql/binlog/mysql-bin.004816|more
复制代码
  1. binlogEstadísticas del tamaño de byte ocupado por el archivo de registro en unidades de transacciones
./mysqlbinlog --no-defaults --base64-output=decode-rows -vv /mysqldata/mysql/binlog/mysql-bin.004816|grep GTID -B1|grep '^# at' | awk '{print $3}' | awk 'NR==1 {tmp=$1} NR>1 {print ($1-tmp, tmp, $1); tmp=$1}'|sort -n -r|more
复制代码

Cierta transacción en producción en realidad ocupa 4 G.

  1. Pase start-positiony stop-positioncuente el tamaño de bytes ocupado por cada SQL de esta transacción
./mysqlbinlog --no-defaults --base64-output=decode-rows --start-position='xxxx' --stop-position='xxxxx' -vv /mysqldata/mysql/binlog/mysql-bin.004816 |grep '^# at'| awk '{print $3}' | awk 'NR==1 {tmp=$1} NR>1 {print ($1-tmp, tmp, $1); tmp=$1}'|sort -n -r|more
复制代码

Se descubrió que el SQL más grande ocupaba 32 millones de tamaño, entonces, ¿cuántos más de 10 millones hay?

  1. Por el número de más de 10M de tamaño
./mysqlbinlog --no-defaults --base64-output=decode-rows --start-position='xxxx' --stop-position='xxxxx' -vv /mysqldata/mysql/binlog/mysql-bin.004816|grep '^# at' | awk '{print $3}' | awk 'NR==1 {tmp=$1} NR>1 {print ($1-tmp, tmp, $1); tmp=$1}'|awk '$1>10000000 {print $0}'|wc -l
复制代码

Los resultados estadísticos muestran que hay más de 200, estimaciones brutas, hay casi 4 G

  1. 根据pos, 我们看下究竟是什么SQL导致的
./mysqlbinlog --no-defaults --base64-output=decode-rows --start-position='xxxx' --stop-position='xxxxx' -vv /mysqldata/mysql/binlog/mysql-bin.004816|grep '^# atxxxx' -C5| grep -v '###' | more
复制代码

根据sql,分析了下,这个表正好有个blob字段,统计了下blob字段总合大概有3个G大小,然后我们业务上有个导入操作,这是一个非常大的事务,会频繁更新这表中记录的更新时间,导致生成binlog非常大。

问题: 明明只是简单的修改更新时间的语句,压根没有动blob字段,为什么生产的binlog这么大?因为生产的binlog采用的是row模式。

binlog的模式

binlog日志记录存在3种模式,而生产使用的是row模式,它最大的特点,是很精确,你更新表中某行的任何一个字段,会记录下整行的内容,这也就是为什么blob字段都被记录到binlog中,导致binlog非常大。此外,binlog还有statementmixed两种模式。

  1. STATEMENT模式 ,基于SQL语句的复制
  • 优点: 不需要记录每一行数据的变化,减少binlog日志量,节约IO,提高性能。
  • 缺点: 由于只记录语句,所以,在statement level下 已经发现了有不少情况会造成MySQL的复制出现问题,主要是修改数据的时候使用了某些定的函数或者功能的时候会出现。
  1. ROW模式,基于行的复制

5.1.5版本的MySQL才开始支持,不记录每条sql语句的上下文信息,仅记录哪条数据被修改了,修改成什么样了。

  • 优点: binlog中可以不记录执行的sql语句的上下文相关的信息,仅仅只需要记录那一条被修改。所以rowlevel的日志内容会非常清楚的记录下每一行数据修改的细节。不会出现某些特定的情况下的存储过程或function,以及trigger的调用和触发无法被正确复制的问题
  • 缺点: 所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,会产生大量的日志内容。
  1. MIXED模式

从5.1.8版本开始,MySQL提供了Mixed格式,实际上就是StatementRow的结合。

Mixed模式下,一般的语句修改使用statment格式保存binlog。如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog

总结

最终分析下来,我们定位到原来是由于大事务+blob字段大致binlog非常大,最终我们采用了修改业务代码,将blob字段单独拆到一张表中解决。所以,在设计开发过程中,要尽量避免大事务,同时在数据库建模的时候特别考虑将blob字段独立成表。

欢迎关注个人公众号【JAVA旭阳】交流学习

Supongo que te gusta

Origin juejin.im/post/7231473194339532861
Recomendado
Clasificación