Pregunta

Tengo un grupo de conexiones MySQL para un servicio de datos basado en la web. Cuando se empieza a atender una solicitud, se necesita una conexión de la agrupación de uso. El problema es que si ha habido una pausa significativa, ya que la conexión se haya agotado, el servidor puede haber cronometrado y cerrado su extremo. Me gustaría ser capaz de detectar esto en el código de gestión de la piscina.

El truco es el siguiente: El medio ambiente en el que estoy de codificación me da solamente una API muy abstracta en la conexión. Puedo básicamente solamente ejecutar sentencias SQL. No tengo acceso a la toma real o acceso directo a la API de cliente de MySQL.

Entonces, la pregunta es: ¿Qué es la declaración de MySQL más barata que pueda ejecutar en la conexión para determinar si está funcionando. Por ejemplo SELECT 1; debería funcionar, pero me pregunto si hay algo aún más barato? Tal vez algo que ni siquiera ir a través del cable, pero se maneja en el lib cliente de MySQL y efectivamente responde a la misma pregunta?

Aclaración: No me preocupa sobre la comprobación de si el servidor MySQL está en funcionamiento, o si se trata de la configuración de la base de datos es lo suficiente como para consultas de respuesta. Si las cosas están abajo, entonces el SQL posterior se ejecuta el servicio recibirá y manejar el error correspondiente. Sólo estoy realmente preocupado con si la conexión TCP está abierto ... ya que si el servidor ha cerrado, entonces SQL del servicio web obtendrá un error que significa "simplemente se vuelven a conectar e inténtelo de nuevo", y que sería un inconveniente para hacer una vez en el el fango del código de servicio.

Cierre: El truco /* ping */ es exactamente el tipo de cosas que estaba buscando, pero por desgracia sólo está disponible a través de JDBC. Lectura a través de la documentación para que el corte, es claro que fue puesto allí por exactamente la misma razón por la que quería. Para los curiosos, estoy trabajando en Haskel , usando HDBC y HDBC-mysql . Voy a pedir al autor de HDBC-MySQL para agregar una forma de mysql_ping() llamada ya sea directamente oa través de un corte similar.

DO 1 de Vlad fue también el tipo de cosas que yo buscaba, y desde el otro truco no está disponible fuera de JDBC, que lo utilizará.

Gracias por todo el gran debate, especialmente @Vlad!

¿Fue útil?

Solución

no conocer el estado real de la conexión sin tener que pasar por encima del alambre , y SELECT 1 es un buen candidato suficiente (posiblemente se podría llegar a un comando más corto que tarda menos tiempo para analizar, pero en comparación con la red o incluso de bucle invertido latencia esos ahorros serían insignificantes.)

Dicho esto, yo diría que ping a una conexión antes comprobar que fuera de la piscina no es el mejor enfoque .

Probablemente debería simplemente tener su gestor de la agrupación de conexiones hacer cumplir su propia política de mantenimiento de conexión (tiempo de espera) para evitar ser desconectado por el servidor (por debajo de un problema más grave conectividad intervenir, lo que podría afectar a usted justo en el medio de las operaciones regulares de todos modos - y el que el gestor de la agrupación de conexiones sería incapaz de ayuda con todos modos), así como a fin de no acaparar la base de datos (piensa filehandles y uso de memoria) sin necesidad .

Por lo tanto es cuestionable, en mi opinión, lo que prueba el valor de condición de conectividad antes de pasar por una conexión de la agrupación realmente tiene. Puede valer la pena estado de la conexión de prueba antes de que una conexión se registró de nuevo en la piscina , pero que se pueden hacer de manera implícita simplemente marcando la conexión tan sucio cuando se genera un error de hardware SQL (o excepción equivalente) ( a menos que la API que está utilizando ya expone una is-bad-como llamada para usted.)

Por lo tanto, yo recomendaría:

  • implementar un policty de mantenimiento de conexión del lado del cliente
  • No realizar ninguna verificación al momento de pagar las conexiones de la piscina
  • realizar comprobaciones sucios antes de que una conexión se devuelve al grupo
  • permitir que el acuerdo con el código de la aplicación de otro (no-tiempo de espera) las condiciones de conexión excepcional

ACTUALIZACIÓN

Al parecer, de sus comentarios que realmente realmente quieren hacer ping a la conexión (supongo que se debe a que no tiene el control total sobre, o tuviera conocimiento de las características de tiempo de espera en el servidor MySQL o intervenir equipos de red tales como proxies etc.)

En este caso se puede usar DO 1 como una alternativa a SELECT 1; es marginalmente más rápido - más corto para analizar, y no devuelve los datos reales (aunque obtener los acks TCP, por lo que aún va a hacer la ida y vuelta validar que el conexión todavía se establece.)

ACTUALIZACIÓN 2

En cuanto a de Joshua puesto , de aquí rastros de captura de paquetes para varios escenarios:

SELECT 1;
13:51:01.463112 IP client.45893 > server.mysql: P 2270604498:2270604511(13) ack 2531191393 win 1460 <nop,nop,timestamp 2983462950 59680547>
13:51:01.463682 IP server.mysql > client.45893: P 1:57(56) ack 13 win 65306 <nop,nop,timestamp 59680938 2983462950>
13:51:01.463698 IP client.45893 > server.mysql: . ack 57 win 1460 <nop,nop,timestamp 2983462951 59680938>

DO 1;
13:51:27.415520 IP client.45893 > server.mysql: P 13:22(9) ack 57 win 1460 <nop,nop,timestamp 2983488906 59680938>
13:51:27.415931 IP server.mysql > client.45893: P 57:68(11) ack 22 win 65297 <nop,nop,timestamp 59681197 2983488906>
13:51:27.415948 IP client.45893 > server.mysql: . ack 68 win 1460 <nop,nop,timestamp 2983488907 59681197>

mysql_ping
14:54:05.545860 IP client.46156 > server.mysql: P 69:74(5) ack 78 win 1460 <nop,nop,timestamp 2987247459 59718745>
14:54:05.546076 IP server.mysql > client.46156: P 78:89(11) ack 74 win 65462 <nop,nop,timestamp 59718776 2987247459>
14:54:05.546092 IP client.46156 > server.mysql: . ack 89 win 1460 <nop,nop,timestamp 2987247459 59718776>

Como se puede ver, excepto por el hecho de que el paquete mysql_ping es de 5 bytes en lugar de DO 1; de 9 bytes, el número de ida y vuelta (y, en consecuencia, la red de latencia inducida) es exactamente la misma. El costo único extra que está pagando con DO 1 en contraposición a mysql_ping es el análisis de DO 1, que es trivial.

Otros consejos

No estoy seguro de qué API que está utilizando actualmente (o qué idioma), pero para Java, hay un truco especial el controlador JDBC puede hacer.

La consulta de prueba estándar es:

select 1

Como se ha indicado. Si lo modifica a:

/* ping */ select 1

el controlador JDBC se dará cuenta de esto, y enviar un solo paquete al servidor MySQL para obtener una respuesta.

Me enteré de este episodio en un Sol 'Deep Dive' titulado Consejos MySQL para desarrolladores de Java Con Marcos Matthews .

Incluso si no está utilizando Java, tal vez este mismo truco se ha implementado en otros controladores de MySQL? Asumo el servidor tendría que ser consciente de este paquete especial para que pueda enviar una respuesta ...

"Conexión" en este caso tiene varios significados. MySQL escucha en un socket- que es el nivel de red "conexión". MySQL mantiene "conexiones de bases de datos", que incluyen un contexto para la ejecución de la consulta y otros gastos generales.

Si lo que desea es saber si el servicio está escuchando, usted debe ser capaz de ejecutar una llamada a nivel de red para ver si el puerto (no sé lo que es el valor por defecto) está escuchando en el IP de destino. Si desea obtener el motor MySQL para responder, creo que su idea es buena, SELECT 1 que en realidad no se ha podido recuperar ningún dato de la base de datos pero sí confirma que el motor se hace girar y responder.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top