Olá DBAs, a vida tá boa?
Passei recentemente por um problema que se mostrou super estranho, não fazia sentido algum, mas depois que se encontram as respostas encaixam as peças de uma maneira absurda.
Um cliente havia migrado um de seus bancos de dados on-premises para cloud OCI Exadata, tudo ocorreu OK na janela de migração, os testes validaram a migração e sendo assim, deram o “GO” como costumamos dizer.
Durante a noite pós a validação da migração, um dos jobs vindos do Control-M (software corporativos gerenciador de Jobs, ele consegue gerenciar/executar jobs em diversos servidores, servindo como um “centralizador”de jobs) não funcionava, começaram as análises relativas a isso, e ficou constatado que o problema estava em uma fase do processo que utilizava um database link que apontava para um banco que ainda estava on-premises.
As validações de teste antes da migração foram as de praxe, ou seja, validação de conexão. Como não era um dblink publico, e não tínhamos acesso ao owner do dblink, as validações feitas se valeram de testes de telnet para a porta, ping entre servidores, transmissão de pacotes de rede e etc… Todos estes testes foram com sucesso, então, em teoria não teriamos problemas com este database link. Bom, não foi o que aconteceu.
Primeiro, foi liberado para nós a senha do owner do database link, para que pudessemos ver na prática o que acontecia, e um “select * from dual” via dblink travava e não retornava nunca mais. Ficava eternamente no prompt, sem retorno.
Checando os eventos da sessão na origem, era possível constatar que tinhamos evento de espera “SQLNet message from dblink” e wait_class “network”. Este primeiros indícios levaram todos nós a crermos que havia algum problema de rede, ou seja, alguma porta no firewall não aberta, alguma das rotas inoperantes, algum controle de saída de dados do banco de destino que não estava respondendo.
Acionada a equipe de firewall e de redes, começaram os testes. Primeiro as mesmas validações feitas anteriormente com testes de telnet nas portas, comunicação entre servidores e etc… Após isso, partimos para testes de tcpdump, analisando em tempo real o que estava acontecendo com a conexão. Estranhamente, nenhuma mensagem de erro, envio dos pacotes corretamente mas algo chamou atenção: Após o “handshake” havia uma sinalização de [F] na comunicação, ou seja, o servidor destino estava solicitando o final de comunicação logo após o “handshake”.
Checando o database de destino, era possível ver que a conexão estava lá, mas em estado “Idle”, aguardando alguma ação, mesmo após o tcpdump mostrar que havia solicitado o final de comunicação. Suspeitamos então de algum problema na camada do aplicativo (neste caso o funcionamento interno do database para chamada de conexão via database link), então decidimos fazer outro tipo de teste que pudesse corroborar ou eliminar essa hipótese. Uma conexão direta via sqlplus do banco de dados origem para o banco de destino, utilizando explicitamente a string de conexão seria o suficiente, pois seria um teste em cima de outra aplicação (o sqlplus) e caso funcionasse, teríamos certeza de que algo internamente no banco estava causando o bloqueio.
Ao testar a conexão, obtivemos o mesmo comportamento:
[oracle@server-origem] sqlplus sys@"(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = scan-serverdestino)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = ORCL_DEST)))" as sysdba
SQL*Plus: Release 12.1.0.2.0 Production on Tue Aug 8 17:48:42 2023
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Enter password:
Ao entrar com a senha, o prompt não retornava mais nada e ficava eternamente piscando esperando alguma ação ou retorno. As verificações de sessão tanto em origem quanto em destino se repetiram com os mesmos eventos, ou seja, reproduzimos o problema de outra maneira, o que eliminou a hipótese de algum problema interno no banco de dados.
Neste ponto, após validações de toda a camada de redes e de banco de dados, envolvemos a Oracle via SR nível 1. Após verificações a Oracle voltou a investigação para algum bloqueio de redes, e pediu que todas as verificações fossem refeitas.
Neste meio tempo, o pessoal do meu time me mostrou o seguinte documento para dar uma analisada:
https://docs.oracle.com/en-us/iaas/Content/Network/Troubleshoot/connectionhang.htm#Finding
Este documento fala basicamente de um problema com o MTU configurado nos servidores, pode sofrer danos, pois deveria ser fragmentado e enviado com sucesso, mas dependendo da configuração (neste caso tínhamos 9000 MTUs configurados em ambos os servidores) pode se perder ao ter que fragmentar os pacotes devido as limitações da rede interna no on-premises ou mesmo em algum hop durante o caminho. O documento fala sobre diversas possibilidades e cenário, mas a imagem abaixo extraída do documento Oracle, ilustra bem o cenário que tínhamos:

Enfrentamos inicialmente uma resistencia do cliente, também enfrentamos o mesmo com a própria Oracle, pois o analista informou que o documento não falava especificamente sobre database links, nem sobre Exadata. Particulamente não fez muito sentido, pois o Exadata era a camada fim após o network, o que fazia total sentido era encarar esse documento como uma possibilidade e fazer os testes descritos.
Após os testes, entramos em outro dilema que era a possibilidade de invalidarmos outros processos ou performance devido a alteração do MTU, que muitas vezes é alterado diretamente na placa. Não tinhamos um ambiente pra testar, o que tornava essa atividade ainda mais desafiadora e temerosa.
O documento mostra a possibilidade de se alterar o MTU somente para uma rota específica, mas mesmo uma alteração como essa em ambiente produtivo, gera um desconforto e muita apreenssão, o que tornava a resolução do problema ainda mais complicada.
Solicitamos então à Oracle a inclusão da equipe de redes deles também, além do pessoal de banco de dados. A nossa intenção era obter com a experiencia deles a informação de que a alteração somente de rota poderia ser sucesso sem afetar outras camadas. O cliente estava apreenssivo, nós estávamos apreenssivos, era um ambiente já produtivo e qualquer erro poderia por muita coisa a perder.
Após horas de análise e discussão sobre o assunto, um dos engenheiros veio com uma informação que eu não tinha até então, a de que era possível alterar a unidade de dado somente a nível de sessão (SDU – Session Data Unit) sem precisar alterar o ambiente em nada, nem rota e nem placa. Uma solução assim faz todo o sentido pra mim, e seria muito menos arriscado e de certa forma muito mais elegante. Eu me lembrava do parametro SDU, como informação default por exemplo no sqlnet.ora, ou mesmo no listener, mas como parametro na string de conexão podendo ser usado no tnsnames ou mesmo explicitamente, foi novidade pra mim.
Pediu então para que fizéssemos a seguinte adição na string de conexão: (SDU=1400).
Haviamos testado o envio de pacotes forçando o MTU e o máximo que chegamos foi a 1472, quando usando 1473 já tinhamos um erro de que o envio estava maior que os 1500 aceitos. Neste caso acreditamos que os 1472 funcionam pois existem mais 28 bytes que seriam nativos do processo de ping, fechando assim os 1500.
Seguindo a orientação para o parametro, alteramos a string que ficou da seguinte maneira:
[oracle@server-origem] sqlplus sys@"(DESCRIPTION = (SDU=1400)(ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = scan-serverdestino)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = ORCL_DEST)))" as sysdba
SQL*Plus: Release 12.1.0.2.0 Production on Tue Aug 8 17:48:42 2023
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Enter password:
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, Oracle Label Security,
OLAP, Advanced Analytics, Oracle Database Vault and Real Application Testing options
SQL>
Conseguimos a conexão, após o hadshake o server destino conseguiu retornar a comunicação sem a solicitação de fim de conexão que pegamos inicialmente no tcpdump. E assim resolvemos um problema que levamos dois dias inteiros para diagnosticar, analisar e solucionar.
O maior detalhe em todo esse processo ao meu ver é que no documento da Oracle, não consta em momento algum que é possível alterar o MTU a nível de sessão, talvez pelo documento não ser especificamente entre conexões de bancos de dados, ou seja lá por que motivo for. Detalhe também que não encontrei essa informação em outros lugares especificamente relacionados ao DB link.
Em resumo, se voce estiver enfrentando problema de conexão do ambiente OCI para on-premises e os testes de rede não mostrarem problema, fazendo o handshake corretamente, conectando no destino e parando logo após, desconfie imediatamente do MTU, pois ele pode ser seu vilão misterioso nesse caso.
Espero que este artigo possa ser de grande valia, e ajude profissionais a perderem bem menos tempo do que eu perdi neste incidente.
Essa é a dica 0800 pra voces desta vez.
“Saber das coisas vale ouro. Compartilhar esse conhecimento não tem preço.”
*** É altamente necessário salientar aqui que ninguém trabalha sozinho, principalmente quando o problema é tão complicado e desafiador assim. Por este motivo, fica aqui o meu agradecimento as pessoas que participaram dessa discussão comigo, enviando documentos, sugestões e visões que ajudaram a chegar nas conclusões e resolver o problema:
- Fábio Aneas
- Tércio Costa (https://oraclepress.wordpress.com/)
- Marcelo Favero
- Vini (https://www.viniciusdba.com.br/blog/)
- Ricardo Rezende
Grandes companheiros que trabalham comigo na mesma empresa atualmente e formam um time super high level.
Seguem referencias:
https://docs.oracle.com/en-us/iaas/Content/Network/Troubleshoot/connectionhang.htm#Finding
https://www.ateam-oracle.com/post/pmtud-importance-and-considerations
https://docs.oracle.com/cd/E11882_01/network.112/e10835/tnsnames.htm#NETRF275
