Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Maneira mais barata de determinar se uma conexão MySQL ainda está ativa


Você não saberá o estado real da conexão sem passar pelo fio e SELECT 1 é um candidato bom o suficiente (sem dúvida, você pode criar um comando mais curto que leve menos tempo para analisar, mas comparado à latência de rede ou mesmo de loopback, essas economias seriam insignificantes).

Dito isso, eu diria que pingar uma conexão antes verificá-lo no pool não é a melhor abordagem .

Você provavelmente deve simplesmente fazer com que seu gerenciador de pool de conexões imponha sua própria política keep-alive (tempo limite) para evitar ser desconectado pelo servidor (a não ser um problema de conectividade mais sério, que poderia afetá-lo no meio de operações regulares de qualquer maneira - e com o qual seu gerenciador de pool de conexões não poderia ajudar de qualquer maneira), bem como para não sobrecarregar o banco de dados (pense em manipuladores de arquivos e uso de memória) desnecessariamente.

Portanto, é questionável, na minha opinião, que valor o teste de condição de conectividade antes de verificar uma conexão do pool realmente tem. Pode valer a pena testar o status da conexão antes que uma conexão seja verificada novamente no pool , mas isso pode ser feito implicitamente simplesmente marcando a conexão como suja quando um erro de SQL (ou exceção equivalente) surge (a menos que a API que você está usando já exponha um is-bad -como ligar para você.)

Recomendo, portanto:
  • implementação de uma política keep-alive do lado do cliente
  • não realizar nenhuma verificação ao fazer check-out de conexões do pool
  • realizando verificações sujas antes que uma conexão seja retornada ao pool
  • deixe o código do aplicativo lidar com outras condições de conexão excepcionais (sem tempo limite)

ATUALIZAÇÃO


Pelos seus comentários, parece que você realmente realmente deseja pingar a conexão (suponho que seja porque você não tem controle total ou conhecimento das características de tempo limite no servidor MySQL ou equipamentos de rede intervenientes, como proxies etc.)

Nesse caso, você pode usar DO 1 como alternativa para SELECT 1; é marginalmente mais rápido -- mais curto para analisar e não retorna dados reais (embora você vai obter o ack TCP s, então você ainda fará a ida e volta validando que a conexão ainda está estabelecida.)

ATUALIZAÇÃO 2


Sobre a postagem de Joshua , aqui estão os rastreamentos de captura de pacotes para vários cenários:
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 você pode ver, exceto pelo fato de que o mysql_ping pacote é de 5 bytes em vez de DO 1; 9 bytes, o número de viagens de ida e volta (e, consequentemente, a latência induzida pela rede) é exatamente o mesmo. O único custo extra que você está pagando com DO 1 ao contrário de mysql_ping é a análise de DO 1 , o que é banal.