O cliente expira, enquanto a consulta MySQL permanece em execução?

9

Tivemos um problema no qual uma consulta somente leitura, executada no ambiente de trabalho MySQL, atingiu o tempo limite da perspectiva da interface do usuário e permaneceu em execução no servidor (e aparentemente consumindo mais e mais recursos) até que tivemos uma interrupção.

Questões

  • Existe uma maneira padrão de lidar com esse tipo de problema no MySQL?
  • Existe uma causa fundamental que precisamos evitar?
asthasr
fonte

Respostas:

11

Você precisa verificar quais valores padrão existem para tempos limite:

mysql> show variables like '%timeout';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| connect_timeout            | 10    |
| delayed_insert_timeout     | 300   |
| innodb_lock_wait_timeout   | 50    |
| innodb_rollback_on_timeout | OFF   |
| interactive_timeout        | 60    |
| net_read_timeout           | 30    |
| net_write_timeout          | 60    |
| slave_net_timeout          | 3600  |
| table_lock_wait_timeout    | 50    |
| wait_timeout               | 60    |
+----------------------------+-------+
10 rows in set (0.00 sec)

Normalmente, observo várias variáveis ​​de tempo limite. Isso é muito imperativo se você usar o MySQL remotamente do MySQL Workbench, cliente mysql ou aplicativo PHP em um servidor de aplicativos que contate o MySQL em um servidor DB.

Aqui está o que a documentação do MySQL diz sobre uma dessas configurações:

  • wait_timeout (Padrão 28800 [8 horas]): o número de segundos que o servidor aguarda atividade em uma conexão não interativa antes de fechá-lo. Esse tempo limite se aplica somente às conexões de arquivo de soquete TCP / IP e Unix, não às conexões feitas usando pipes nomeados ou memória compartilhada. Na inicialização do encadeamento, o valor wait_timeout da sessão é inicializado a partir do valor global wait_timeout ou do valor global interactive_timeout, dependendo do tipo de cliente (conforme definido pela opção de conexão CLIENT_INTERACTIVE para mysql_real_connect ()). Veja também interactive_timeout.
  • interactive_timeout (Padrão 28800 [8 horas]): o número de segundos que o servidor aguarda atividade em uma conexão interativa antes de fechá-la. Um cliente interativo é definido como um cliente que usa a opção CLIENT_INTERACTIVE para mysql_real_connect (). Veja também wait_timeout.
  • net_read_timeout (Padrão 30): o número de segundos para aguardar mais dados de uma conexão antes de interromper a leitura. Quando o servidor está lendo do cliente, net_read_timeout é o valor do tempo limite que controla quando cancelar. Quando o servidor está gravando no cliente, net_write_timeout é o valor do tempo limite que controla quando cancelar. Veja também slave_net_timeout.
  • net_write_timeout (Padrão 60): o número de segundos para aguardar que um bloco seja gravado em uma conexão antes de interromper a gravação. Veja também net_read_timeout.

Certifique-se de que esses tempos limite estejam altos o suficiente para acomodar consultas que podem ser executadas por um período muito longo, o que pode incluir:

  • Massa UPDATEs
  • Massa DELETEs
  • ENABLE KEYS em um grande MyISAM

Para lidar com consultas que continuam em execução depois que você perde o contato, é necessário executar KILL no ID do processo da consulta de execução longa. Mesmo com o comando KILL, você terá que aguardar qualquer consulta que esteja no meio de etapas intensivas em disco ou que tenham mutexes internos em andamento.

RolandoMySQLDBA
fonte
Existe uma maneira padrão e robusta de executar o KILL em processos que já estão em execução há muito tempo, ou isso geralmente é feito por meio de um trabalho de script / cron do bash?
asthasr
Na verdade, eu escrevi uma volta pós maio 2011 sobre como iniciar um script usando o information_schema para matar um monte de conexões DB: dba.stackexchange.com/a/2637/877
RolandoMySQLDBA
"Certifique-se de que esses tempos limite sejam altos o suficiente para acomodar consultas que podem ser executadas por um período muito longo, que pode incluir: UPDATEs em massa ..." exemplo: php + mysql, eu tenho que selecionar todos os registros de uma coluna da tabela, então busque linhas e, em seguida, faça algo ... atualize outro registro com um novo valor. Coloque o caso de que esse script requer cerca de 5 minutos ou mais. Um SELECT no início e um UPDATE no final, buscam linhas e fazem ... no meio. Você pode explicar o que tem de fazer o wait_timeout com essa situação? Realmente não é claro para mim ... o que é um valor seguro para wait_timeout ao recurso livre