by Vasiliy Ovchinnikov
Introdução
Nos sistemas com bancos InterBase ou Firebird, feitos para trabalhar em tempo real ou quase em tempo real, há o problema de acompanhar o status da conexão do cliente no servidor e de desconectar à força quando o cliente fica inacessível porque a conexão caiu.
É importante liberar logo os recursos ocupados por essas conexões fantasma, principalmente em servidores com arquitetura Classic. Se alguns usuários entram por uma conexão de modem instável, o risco de queda é alto.
Por exemplo, o cliente grava um conjunto de registros alterado e, depois do UPDATE (sem o COMMIT), a conexão cai.
Em geral, o aplicativo cliente reconecta ao servidor, mas o cliente (que continua trabalhando com os dados cuja gravação falhou por causa da queda) não consegue salvar as mudanças: recebe um conflito de bloqueio ("lock conflict on update"). A conexão anterior, que abriu a transação (na qual o UPDATE foi executado e o COMMIT não), ainda segura esses registros.
Quedas também acontecem na rede local, se o hardware (placas de rede, hubs, comutadores) está com defeito ou mal ajustado, e/ou por congestionamento. Nos logs do InterBase e do Firebird, falhas de conexão TCP aparecem como erro 10054 no Windows e 104 no Unix; falhas NetBEUI aparecem como erros 108/109.
Métodos de controle de conexões presas
No InterBase e no Firebird, os mecanismos de pacotes DUMMY ou de sockets KEEPALIVE acompanham e desativam essas conexões "mortas".
No InterBase 5.0 e posteriores, o mecanismo de pacotes DUMMY fica na camada de aplicação, entre o servidor InterBase/Firebird e a biblioteca cliente gds32/fbclient. Ele está no ibconfig/firebird.conf e não é o assunto deste artigo.
Nota
Pela experiência anterior, a estabilidade do mecanismo de pacotes dummy (o do InterBase 5.0, corrigido várias vezes no Firebird 1.5.x) depende muito do sistema do servidor e do cliente, das versões da pilha TCP e de outras condições. Na prática, a eficácia desse sistema numa rede real tende a zero.
Os sockets KEEPALIVE são um mecanismo mais interessante. Implementado no InterBase 6.0 e posteriores, serve para detectar queda de conexão. O KEEPALIVE é ativado pela opção de socket SO_KEEPALIVE na abertura. Não é preciso configurá-la à mão no Firebird 1.5 ou superior: ela já está no código do servidor Firebird, tanto no Classic quanto no Superserver.
No InterBase e no Firebird anteriores à 1.5, na variante Classic, é preciso um ajuste extra. Esse ajuste está descrito abaixo.
Nesse caso, a pilha TCP do sistema operacional (e não o servidor Firebird) passa a responder pelo status da conexão. Para o mecanismo funcionar, é preciso ajustar os parâmetros KEEPALIVE.
Descrição do KEEPALIVE
O comportamento dos sockets KEEPALIVE é controlado pelos parâmetros da tabela a seguir.
| Parâmetro | Descrição |
|---|---|
| KEEPALIVE_TIME | Intervalo após o qual começam as sondas KEEPALIVE |
| KEEPALIVE_INTERVAL | Intervalo entre as sondas KEEPALIVE |
| KEEPALIVE_PROBES | Quantidade de sondas KEEPALIVE |
A pilha TCP observa o momento em que os pacotes param de circular entre o cliente e o servidor e dispara o temporizador KEEPALIVE. Quando o temporizador chega a KEEPALIVE_TIME, a pilha TCP do servidor envia a primeira sonda KEEPALIVE. A sonda é um pacote vazio com a flag ACK, enviado ao usuário. Se o cliente está bem, a pilha TCP dele responde com um pacote ACK, e a pilha do servidor zera o temporizador KEEPALIVE ao receber a resposta.
Se o cliente não responde à sonda, o servidor continua enviando sondas. A quantidade é o valor de KEEPALIVE_PROBES, no intervalo KEEPALIVE_INTERVAL. Se o cliente não responde à última sonda, depois de mais um KEEPALIVE_INTERVAL a pilha TCP do sistema fecha a conexão, e o servidor (neste caso, a instância do InterBase ou do Firebird) libera os recursos daquela conexão.
Assim, uma conexão de cliente com falha é fechada depois deste intervalo:
KEEPALIVE_TIME+ ( KEEPALIVE_PROBES+1)* KEEPALIVE_INTERVAL.
Por padrão, os valores são grandes demais e o uso fica pouco eficaz. Por exemplo, o padrão de KEEPALIVE_TIME é "2 horas", no Linux e no Windows. Na prática, 1 ou 2 minutos bastam para decidir a desconexão forçada de um cliente inacessível. Por outro lado, o padrão do KEEPALIVE às vezes força desconexões em redes Windows que ficam inativas essas 2 horas (dá para questionar se essas conexões são necessárias no aplicativo, mas isso é outro assunto).
Abaixo está o ajuste desses parâmetros no Windows e no Linux.
Configuração do KEEPALIVE no Linux
No Linux, os parâmetros KEEPALIVE podem ser alterados editando o sistema de arquivos /proc ou chamando o sysctl.
No primeiro caso, edite estas linhas:
/proc/sys/net/ipv4/tcp_keepalive_time /proc/sys/net/ipv4/tcp_keepalive_intvl /proc/sys/net/ipv4/tcp_keepalive_probes
No segundo caso, execute estes comandos:
sysctl -w net.ipv4.tcp_keepalive_time=value sysctl -w net.ipv4.tcp_keepalive_intvl=value sysctl -w net.ipv4.tcp_keepalive_probes=value
O tempo é expresso em segundos.
Para aplicar esses parâmetros automaticamente na reinicialização do servidor, inclua o seguinte:
net.ipv4.tcp_keepalive_intvl = value net.ipv4.tcp_keepalive_time = value net.ipv4.tcp_keepalive_probes = value
Substitua a palavra <value> pelos valores necessários.
Se você usa o Firebird Classic anterior à 1.5, inclua o seguinte em /etc/xinet.d/firebird:
FLAGS=REUSE KEEPALIVE
Ajuste do KEEPALIVE no Windows 95/98/ME
Ramo do registro:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP
O ajuste de TCP está descrito aqui:
http://support.microsoft.com/default.aspx?scid=kb;en-us;158474
Parâmetros:
-
KeepAliveTime = millisecondsType: DWORDNo Windows 98, tipo STRING.Define o tempo de inatividade da conexão, em milissegundos.Quando esse tempo acaba, as sondas KEEPALIVE começam.O valor padrão é 2 horas (7200000).
-
KeepAliveInterval = 32-digit valueType: DWORDNo Windows 98, tipo STRING.Define o tempo entre as sondas KEEPALIVE (em milissegundos).Quando o intervalo KeepAliveTime acaba,a cada KeepAliveInterval (em milissegundos)são enviadas sondas KEEPALIVE, no máximoMaxDataRetries. Se não houver resposta, a conexãoé fechada. O valor padrão é 1 segundo (1000).
-
MaxDataRetries = 32-digit valueType: STRINGDefine a quantidade máxima de sondas KEEPALIVE.O valor padrão é 5.
Configuração do KEEPALIVE no Windows 2000/NT/XP
Ramo do registro:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\.
Ajuste de TCP:
XP: http://support.microsoft.com/kb/314053
O parâmetro MaxDataRetries é substituído por TCPMaxDataRetransmissions.
Os demais parâmetros têm os mesmos nomes do Windows 9x
Configuração do KEEPALIVE no Windows (para clientes)
Este ajuste é opcional, mas pode reduzir as mensagens de falha de conexão em canais instáveis. Inclua no ramo do registro:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
o parâmetro DisableDHCPMediaSense=1. A descrição está aqui:
Exemplo
Veja o ajuste do Firebird SQL Server 1.5.2 CS no Linux.
-
Confira se o mecanismo de pacotes DUMMY está desativado no firebird.conf(o parâmetro está comentado).......#DummyPacketsInterval=0......
-
Confira se existe o arquivo de configuração /etc/xinet.d/firebird
Deixamos tudo como ficou na instalação. Não é preciso incluir nada.
-
Altere os parâmetros da pilha TCP:
sysctl -w net.ipv4.tcp_keepalive_time = 15 sysctl -w net.ipv4.tcp_keepalive_intvl = 10 sysctl -w net.ipv4.tcp_keepalive_probes = 5
-
Conecte em qualquer banco do servidor a partir de um cliente da rede
-
Confira o tráfego no servidor com qualquer filtro de pacotes.
Com os parâmetros em /proc/sys/net/tcp_keepalive_*, em até 15 segundos depois que o canal para, o servidor cria uma sonda. Se o cliente está "vivo", o servidor recebe um pacote de resposta. 15 segundos depois, a verificação se repete, e assim por diante.
-
Se o cliente é desligado fisicamente (o multiplexador ou o modem desliga de repente — tudo é possível), o servidor não recebe resposta e passa a enviar sondas a cada 10 segundos. Se o cliente não responde à quinta sonda, 10 segundos depois o processo do servidor encerra e libera recursos e bloqueios. Se o cliente dá algum sinal e responde pelo menos à quinta sonda (no pior caso), depois de mais 15 segundos de tempo limite o servidor volta a enviar sondas. E assim por diante.
Orientações
Para fechar, algumas orientações sobre como escolher os valores de KEEPALIVE.
Primeiro, defina o KEEPALIVE_TIME necessário. Quanto maior o valor, mais tarde começam as sondas KEEPALIVE. Se você vê o tempo todo erros 10054/104 no log do servidor e precisa apagá-los à mão, o recomendado é aumentar o KEEPALIVE_TIME.
Depois, KEEPALIVE_INTERVAL e KEEPALIVE_PROBES precisam atender à liberação antecipada das conexões já presas. Se os usuários entram por canais instáveis, provavelmente você vai querer mais sondas e um intervalo maior entre elas, para o usuário perceber a falha e reconectar. Se os clientes usam DSL ou acessam o servidor SQL pela rede local, dá para diminuir o intervalo entre as sondas KEEPALIVE.
Recomendação geral: se os clientes recebem muitas mensagens de erro ao salvar, por conflito de bloqueio, sem motivo aparente (não há conexões concorrentes nos mesmos dados), aumente a reação do sistema à liberação das conexões presas. Na prática, KEEPALIVE_TIME pode ser de 1 minuto ou mais. Estime o tempo da transação mais longa, para o tráfego não ficar sobrecarregado com verificações KEEPALIVE de conexões normais que abriram transações longas. KEEPALIVE_INTERVAL fica em 10 segundos ou mais, e KEEPALIVE_PROBES em 5 verificações ou mais. Com muitos usuários ao mesmo tempo, lembre que verificar com muita frequência pode aumentar bastante o tráfego da rede.
Lembre também que, se os usuários alteram dados em comum com frequência, erros de bloqueio vão ocorrer mesmo numa situação normal. Nesse caso, o aplicativo cliente precisa tratar o erro de bloqueio corretamente. Ao mesmo tempo, o aplicativo deve reduzir a ocorrência desses erros.
Exemplos de configuração padrão
Por fim, mais alguns exemplos de configuração padrão. O tempo de indisponibilidade é o período em que os usuários não conseguem atualizar dados (que naquele momento foram atualizados pela transação aberta pela conexão presa). O tempo total é o prazo após o qual a conexão presa é fechada.
-
Clientes usam conexão por modem; a maioria das transações do sistema é curta; a indisponibilidade fica limitada a 3 minutos:
KEEPALIVE_TIME 1 minutes KEEPALIVE_PROBES 3 KEEPALIVE_INTERVAL 30 seconds TOTAL 3 minutes
-
Clientes usam a LAN; a maioria das transações do sistema é curta; a indisponibilidade fica limitada a 2 minutos:
KEEPALIVE_TIME 30 sec KEEPALIVE_PROBES 5 KEEPALIVE_INTERVAL 10 sec TOTAL 90 seconds
-
Clientes usam qualquer conexão; a indisponibilidade não é limitada:
KEEPALIVE_TIME12 minutes KEEPALIVE_PROBES 7 KEEPALIVE_INTERVAL 15 sec TOTAL 14 minutes
Esperamos que os exemplos bastem para ajustar corretamente o mecanismo KEEPALIVE da pilha TCP.
Fonte: