Un estudio de caso de interrupción de la conexión MySQL causada por una sobrecarga de caché TCP

¿Cómo analizar la posibilidad de apuntar a otros factores además del propio MySQL?

Autor: Gong Tangjie, miembro del equipo de ACOS DBA, es el principal responsable del soporte técnico de MySQL y es bueno en MySQL, PG y bases de datos nacionales.

Producido por la comunidad de código abierto de Aikeson, el contenido original no se puede utilizar sin autorización. Comuníquese con el editor e indique la fuente para la reimpresión.

Este artículo tiene aproximadamente 1200 palabras y se espera que demore 3 minutos en leerlo.

fondo

Durante la ejecución de tareas por lotes, la aplicación encontró un problema: la conexión a la base de datos para algunas tareas se perdía repentinamente, lo que provocaba que la tarea no pudiera completarse. Del registro de errores de la base de datos se encontró información de conexión cancelada , lo que indica que la comunicación entre el cliente y el servidor se interrumpió de manera anormal.

analizar

Para descubrir la causa del problema, primero analizamos varias situaciones comunes que pueden provocar que se cancele la conexión según la experiencia:

  1. El cliente no cerró la conexión correctamente y no llamó mysql_close()a la función.
  2. Si el tiempo de inactividad del cliente excede wait_timeoutlos interactive_timeoutsegundos del parámetro o, el servidor se desconecta automáticamente.
  3. El tamaño del paquete enviado o recibido por el cliente excede max_allowed_packetel valor del parámetro, provocando que se interrumpa la conexión.
  4. El cliente intentó acceder a la base de datos pero no tenía permiso, utilizó una contraseña incorrecta o el paquete de conexión no contenía la información correcta.

Sin embargo, después de la investigación, se encontró que ninguna de las situaciones anteriores se aplica al problema actual. Debido a que las tareas se ejecutaban normalmente antes y el programa no ha cambiado, se puede descartar la primera situación. Verifiqué los parámetros de tiempo de espera de MySQL wait_timeouty interactive_timeoutdescubrí que ambos son 28800, que son 8 horas, lo que excede con creces el tiempo de ejecución de la tarea, por lo que se puede descartar la segunda situación. También verifiqué max_allowed_packetlos parámetros del cliente y del servidor y descubrí que ambos son 64M y es poco probable que excedan este límite, por lo que se puede descartar la tercera situación. También hemos confirmado que los derechos de acceso a la base de datos del cliente, la contraseña, el paquete de conexión y otra información son correctos, por lo que se puede descartar la cuarta situación.

En este punto, inicialmente sentimos que no debería haber ningún problema a nivel de MySQL y que el problema puede estar en otra parte.

Para localizar mejor el problema, intentamos modificar algunos parámetros relevantes del kernel del servidor, de la siguiente manera:

net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_time = 120
net.core.rmem_default = 2097152
net.core.wmem_default = 2097152
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_syn_backlog = 16384

Estos parámetros sirven principalmente para optimizar el rendimiento y la estabilidad de la conexión de red y evitar que la conexión se cierre inesperadamente o se agote el tiempo de espera. Sin embargo, los resultados modificados no han mejorado y la conexión seguirá interrumpiéndose de forma anormal.

Finalmente, probamos el análisis de captura de paquetes. Utilizando la herramienta Wireshark , descubrimos un fenómeno anormal: el servidor enviaba una gran cantidad de paquetes ACK al cliente. Como se muestra abajo:

Estos paquetes ACK son paquetes de confirmación en el protocolo TCP, que indican que el servidor ha recibido el paquete de datos del cliente y le solicita que continúe enviando datos. Pero ¿por qué el servidor envía tantos paquetes ACK? Especulamos que puede haber una anomalía en la red, lo que hace que el cliente no reciba el paquete ACK devuelto por el servidor, por lo que el servidor enviará paquetes ACK repetidamente hasta que se agote el tiempo de espera o reciba una respuesta del cliente. Sin embargo, después de una investigación realizada por el personal de la red, no se encontraron problemas obvios.

Continuando con el análisis de la captura de paquetes, descubrimos otro fenómeno anormal: el cliente dará algunas ventanas de advertencia al servidor emisor. Como se muestra abajo:

Estas advertencias de ventana son un mecanismo de control de flujo en el protocolo TCP, que indica que la ventana de recepción del servidor o cliente está llena y no puede recibir más datos.

[Ventana TCP llena] es una ventana de advertencia enviada por el remitente al receptor, indicando que se ha alcanzado el límite del receptor de datos.

[TCP ZeroWindow] es una advertencia de ventana enviada por el extremo receptor al extremo emisor, que le dice al remitente que la ventana de recepción del extremo receptor está llena y deja de enviar temporalmente.

Con base en la información anterior, especulamos que la causa del problema es: debido a que los datos que MySQL necesita enviar son demasiado grandes, el caché TCP del cliente está lleno, por lo que debe esperar a que el cliente digiera los datos en el TCP. caché antes de que pueda continuar recibiendo datos. Sin embargo, durante este período, MySQL seguirá solicitando al cliente que continúe enviando datos. Si el cliente no responde dentro de un cierto período de tiempo (el valor predeterminado es 60 segundos), MySQL considerará que el envío de datos se ha agotado e interrumpirá la conexión.

Para verificar la especulación, verifiqué el registro lento de MySQL y encontré muchos registros Last_errno: 1161 .

Estos registros indican que MySQL encontró un error de tiempo de espera al enviar datos, y la cantidad de ocurrencias es muy cercana a la cantidad de tareas fallidas de la aplicación. Según el sitio web oficial de MySQL, el significado de este error es:

Número de error: 1161; Símbolo: ER_NET_WRITE_INTERRUPTED; ESTADOSQL: 08S01

Mensaje: Se agotó el tiempo de espera para escribir paquetes de comunicación

Se puede ver que esto significa que la escritura de la red se interrumpe y hay un parámetro en el nivel de MySQL para controlar esto, así que intente cambiar el parámetro net_write_timeout a 600 y la tarea por lotes se ejecutará normalmente.

Por lo tanto, la razón por la que la conexión MySQL se interrumpe anormalmente es porque la base de datos obtenida por el cliente es demasiado grande y excede el caché TCP del cliente. Durante este período, MySQL continuará solicitando. El cliente continuó enviando datos, pero el cliente no respondió dentro de los 60 segundos, lo que provocó que MySQL expirara el tiempo de envío de datos e interrumpiera la conexión.

en conclusión

A través del análisis y los intentos anteriores, hemos llegado a las siguientes conclusiones:

  • En la información de captura de paquetes, hay mucha información ACK porque la caché del cliente está llena y no puede enviar información al servidor a tiempo, por lo que el servidor enviará información ACK repetidamente hasta que pasen más de 60 segundos ( net_write_timeoutel valor predeterminado es 60), lo que provocará MySQL para interrumpir la conexión.
  • En el registro lento, hay muchos registros Last_errno: 1161 porque SQL en realidad se ejecutó en MySQL, pero al enviar datos al cliente, la cantidad de datos excede el caché TCP del cliente, y luego el cliente La aplicación no procesó el datos en el caché en 60 segundos, lo que hace que MySQL agote el tiempo de espera al enviar datos al cliente.
  • Ajustar net_write_timeoutlos parámetros a nivel de MySQL solo puede aliviar este fenómeno. La causa principal es que la cantidad de datos obtenidos por un solo SQL es demasiado grande y excede el tamaño de la caché del cliente. lo que hace que se agote el tiempo de espera para el envío de datos posteriores.

Sugerencias de optimización

  • Los datos se procesan en lotes a nivel empresarial para evitar que una única consulta SQL obtenga una gran cantidad de datos del servidor, lo que resulta en una caché TCP insuficiente en el lado del cliente.
  • Aumentar los parámetros en MySQL net_write_timeouto aumentar el caché TCP del cliente puede aliviar esta situación, pero no puede resolver completamente el problema porque demasiados datos seguirán afectando el rendimiento y la estabilidad.
  • Optimice las declaraciones SQL para reducir las devoluciones de datos innecesarias, como el uso de LIMIT, WHERE y otras condiciones, o el uso de funciones agregadas, funciones de agrupación, etc., para reducir la cantidad de datos y mejorar la eficiencia de las consultas.

Para obtener más artículos técnicos, visite: https://opensource.actionsky.com/

Acerca de SQLE

SQLE es una plataforma integral de gestión de calidad de SQL que cubre la auditoría y gestión de SQL desde los entornos de desarrollo hasta los de producción. Admite bases de datos nacionales, comerciales y de código abierto convencionales, proporciona capacidades de automatización de procesos para el desarrollo, operación y mantenimiento, mejora la eficiencia en línea y mejora la calidad de los datos.

obtener SQLE

tipo DIRECCIÓN
Repositorio https://github.com/actiontech/sqle
documento https://actiontech.github.io/sqle-docs/
noticias de lanzamiento https://github.com/actiontech/sqle/releases
Documentación de desarrollo del complemento de auditoría de datos https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse
Linus tomó el asunto en sus propias manos para evitar que los desarrolladores del kernel reemplacen las pestañas con espacios. Su padre es uno de los pocos líderes que puede escribir código, su segundo hijo es el director del departamento de tecnología de código abierto y su hijo menor es un núcleo. Colaborador de código abierto Huawei: tomó 1 año convertir 5000 aplicaciones móviles de uso común Migración completa a Hongmeng Java es el lenguaje más propenso a vulnerabilidades de terceros Wang Chenglu, el padre de Hongmeng: el código abierto Hongmeng es la única innovación arquitectónica. En el campo del software básico en China, Ma Huateng y Zhou Hongyi se dan la mano para "eliminar rencores". Ex desarrollador de Microsoft: el rendimiento de Windows 11 es "ridículamente malo " " Aunque lo que Laoxiangji es de código abierto no es el código, las razones detrás de él. Son muy conmovedores. Meta Llama 3 se lanza oficialmente. Google anuncia una reestructuración a gran escala.
{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/actiontechoss/blog/11054532
Recomendado
Clasificación