Archivo de la categoría: Linux

Oracle SQL Developer se cuelga en Linux

Oracle SQL Developer se cuelga en Linux

Este artículo fue publicado originalmente por Alexey Moseyev el 24 de Junio de 2012. Lo copio (y traduzco) aquí para referencia futura habiendo tenido que usarlo ya más de una vez.

Si usas SQL Developer 3.x en Linux (probado en Ubuntu, RHEL, pero aplicable a otras distribuciones, y puede ocurrir en Mac) y no recuerdas la última vez que lo cerraste limpiamente, en vez de matarlo con xkill todo el tiempo porque se CUEEEEEEEEEELGA, continúa leyendo al menos los próximos 20 renglones, podría resultarte de mucha utilidad.

La situación es la siguiente:
Pasado algún tiempo ocioso, o luego de desconectarte de una vpn/red, intentas hacer algo (aunque sea cerrar la ventana, o abrir una nueva sesión, o realmente – cualquier cosa) SQL developer se cuelga durante 15-18 minutos. Y puede escalar a colgar por completo la sesión de gnome, de fomra que ni siquiera puedes hacer Ctrl+Alt+F1 para matar al sqldeveloper..

1.
Para solucionar el cuelgue luego de tiempo ocioso, y ademas, evitar la mayoría de los errores de “connection closed” (conexión cerrada):

Descarga libkeepalive-0.2.tar.gz de http://libkeepalive.sourceforge.net

$ tar xvf libkeepalive-0.2.tar.gz
$ cd libkeepalive-0.2
$ make
$ sudo cp libkeepalive.so /lib/
$ which sqldeveloper
/usr/local/bin/sqldeveloper
Edita el archivo anterior y remplaza la linea que dice:
/opt/sqldeveloper/sqldeveloper.sh
por:
LD_PRELOAD=/lib/libkeepalive.so KEEPCNT=2 KEEPIDLE=30 KEEPINTVL=30 /opt/sqldeveloper/sqldeveloper.sh

2.
Para solucionar el cuelgue luego de una desconexión:

# echo "net.ipv4.tcp_retries2=5" >> /etc/sysctl.conf
# sysctl -p

Deshablita IPV6:

# echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf
# echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf
# echo "net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf
# sysctl -p

Si esto te ayudó, – eso es todo, puedes ignorar lo que sigue a continuación.

Pero si estás interesado en saber por qué se cuelga – continúa leyendo.

Justo antes de que se cuelgue habilita el debugging básico en el equipo donde SQL Developer está fcorriendo:

En una primera ventana / terminal ejecuta:

$ ps -ef | grep sqldeve
amoseyev  4637     1  0 Jun22 ?        00:00:00 /bin/sh /usr/local/bin/sqldeveloper
amoseyev  4639  4637  0 Jun22 ?        00:00:00 /bin/bash /opt/sqldeveloper/sqldeveloper.sh
amoseyev  4642  4639  0 Jun22 ?        00:00:00 bash sqldeveloper
amoseyev  4699  4642  1 Jun22 ?        00:21:00 /usr/lib/jvm/java-6-sun/bin/java -Xmx640M -Xms128M -Xverify:none -Doracle.ide.util.AddinPolicyUtils.OVERRIDE_FLAG=true -Dsun.java2d.ddoffscreen=false -Dwindows.shell.font.languages= -XX:MaxPermSize=128M -Doracle.jdbc.mapDateToTimestamp=false -Dide.AssertTracingDisabled=true -Doracle.ide.util.AddinPolicyUtils.OVERRIDE_FLAG=true -Djava.util.logging.config.file=logging.conf -Dsqldev.debug=false -Dide.conf="/opt/sqldeveloper/sqldeveloper/bin/sqldeveloper.conf" -Dide.startingcwd="/opt/sqldeveloper/sqldeveloper/bin" -classpath ../../ide/lib/ide-boot.jar oracle.ide.boot.Launcher
amoseyev 12609 12170  0 01:23 pts/3    00:00:00 grep --color=auto sqldeve
 
# strace -e trace=network -f -p 4699

En una segunda ventana / terminal ejecuta:

$ netstat -n | grep 1521
tcp        0      0 10.4.4.51:49261         172.18.99.69:1521       ESTABLISHED
 
# tcpdump -lnni tun0 host 172.18.99.69 and dst port 1521 -vvv

Haz que sqldeveloper se cuelgue, y luego de 15-18 minutes (una vez que termine de pensar) ejecuta:

En la primera terminal:

# strace -e trace=network -f -p 4699
...
[pid 32467] 17:27:08  0x823a0770, 8192, 0) = -1 ETIMEDOUT (Connection timed out)
[pid 32467] 17:27:08 send(232, "\0\n\0\0\6\0\0\0\0@", 10, 0) = -1 EPIPE (Broken pipe)

En la segunda terminal:

# tcpdump -lnni tun0 host 172.18.99.69 and dst port 1521 -vvv
 
17:14:51.924676 IP (tos 0x0, ttl 64, id 28812, offset 0, flags [DF], proto TCP (6), length 151)
    10.181.70.57.39292 > 10.168.66.198.1521: Flags [P.], cksum 0x04f0 (correct), seq 7433:7532, ack 10119, win 1005, options [nop,nop,TS val 39292289 ecr 3105462411], length 99
17:14:52.451556 IP (tos 0x0, ttl 64, id 28813, offset 0, flags [DF], proto TCP (6), length 151)
    10.181.70.57.39292 > 10.168.66.198.1521: Flags [P.], cksum 0x046c (correct), seq 7433:7532, ack 10119, win 1005, options [nop,nop,TS val 39292421 ecr 3105462411], length 99
17:14:53.511511 IP (tos 0x0, ttl 64, id 28814, offset 0, flags [DF], proto TCP (6), length 151)
    10.181.70.57.39292 > 10.168.66.198.1521: Flags [P.], cksum 0x0363 (correct), seq 7433:7532, ack 10119, win 1005, options [nop,nop,TS val 39292686 ecr 3105462411], length 99
17:14:55.631544 IP (tos 0x0, ttl 64, id 28815, offset 0, flags [DF], proto TCP (6), length 151)
    10.181.70.57.39292 > 10.168.66.198.1521: Flags [P.], cksum 0x0151 (correct), seq 7433:7532, ack 10119, win 1005, options [nop,nop,TS val 39293216 ecr 3105462411], length 99
17:14:59.871499 IP (tos 0x0, ttl 64, id 28816, offset 0, flags [DF], proto TCP (6), length 151)
    10.181.70.57.39292 > 10.168.66.198.1521: Flags [P.], cksum 0xfd2c (correct), seq 7433:7532, ack 10119, win 1005, options [nop,nop,TS val 39294276 ecr 3105462411], length 99
17:15:08.335490 IP (tos 0x0, ttl 64, id 28817, offset 0, flags [DF], proto TCP (6), length 151)
    10.181.70.57.39292 > 10.168.66.198.1521: Flags [P.], cksum 0xf4e8 (correct), seq 7433:7532, ack 10119, win 1005, options [nop,nop,TS val 39296392 ecr 3105462411], length 99
17:15:25.263514 IP (tos 0x0, ttl 64, id 28818, offset 0, flags [DF], proto TCP (6), length 151)
    10.181.70.57.39292 > 10.168.66.198.1521: Flags [P.], cksum 0xe460 (correct), seq 7433:7532, ack 10119, win 1005, options [nop,nop,TS val 39300624 ecr 3105462411], length 99
17:15:59.119517 IP (tos 0x0, ttl 64, id 28819, offset 0, flags [DF], proto TCP (6), length 151)
    10.181.70.57.39292 > 10.168.66.198.1521: Flags [P.], cksum 0xc350 (correct), seq 7433:7532, ack 10119, win 1005, options [nop,nop,TS val 39309088 ecr 3105462411], length 99
17:17:06.831496 IP (tos 0x0, ttl 64, id 28820, offset 0, flags [DF], proto TCP (6), length 151)
    10.181.70.57.39292 > 10.168.66.198.1521: Flags [P.], cksum 0x8130 (correct), seq 7433:7532, ack 10119, win 1005, options [nop,nop,TS val 39326016 ecr 3105462411], length 99
17:19:06.895498 IP (tos 0x0, ttl 64, id 28821, offset 0, flags [DF], proto TCP (6), length 151)
    10.181.70.57.39292 > 10.168.66.198.1521: Flags [P.], cksum 0x0bf0 (correct), seq 7433:7532, ack 10119, win 1005, options [nop,nop,TS val 39356032 ecr 3105462411], length 99
17:21:07.215506 IP (tos 0x0, ttl 64, id 28822, offset 0, flags [DF], proto TCP (6), length 151)
    10.181.70.57.39292 > 10.168.66.198.1521: Flags [P.], cksum 0x966f (correct), seq 7433:7532, ack 10119, win 1005, options [nop,nop,TS val 39386112 ecr 3105462411], length 99
17:23:07.535497 IP (tos 0x0, ttl 64, id 28823, offset 0, flags [DF], proto TCP (6), length 151)
    10.181.70.57.39292 > 10.168.66.198.1521: Flags [P.], cksum 0x20ef (correct), seq 7433:7532, ack 10119, win 1005, options [nop,nop,TS val 39416192 ecr 3105462411], length 99
17:25:07.855511 IP (tos 0x0, ttl 64, id 28824, offset 0, flags [DF], proto TCP (6), length 151)
    10.181.70.57.39292 > 10.168.66.198.1521: Flags [P.], cksum 0xab6e (correct), seq 7433:7532, ack 10119, win 1005, options [nop,nop,TS val 39446272 ecr 3105462411], length 99
17:25:07.855511 IP (tos 0x0, ttl 64, id 28824, offset 0, flags [DF], proto TCP (6), length 151)
    10.181.70.57.39292 > 10.168.66.198.1521: Flags [P.], cksum 0xab6e (correct), seq 7433:7532, ack 10119, win 1005, options [nop,nop,TS val 39446272 ecr 3105462411], length 99
17:25:07.855511 IP (tos 0x0, ttl 64, id 28824, offset 0, flags [DF], proto TCP (6), length 151)
    10.181.70.57.39292 > 10.168.66.198.1521: Flags [P.], cksum 0xab6e (correct), seq 7433:7532, ack 10119, win 1005, options [nop,nop,TS val 39446272 ecr 3105462411], length 99

Tenemos entonces, 15 TCP retransmission timeouts (RTO). Y por defecto net.ipv4.tcp_retries2=15. entonces SQL developer esperó el timeout de TCP..

En "Oracle Database JDBC Developer’s Guide and Reference guide" (http://docs.oracle.com/cd/B28359_01/java.111/b31224/apxtblsh.htm)
Bajo el título “Using JDBC with Firewalls” dice:

Pass oracle.net.READ_TIMEOUT as connection property to enable read timeout on socket. The timeout value is in milliseconds.

(Pasa el parametro oracle.net.READ_TIMEOUT como propiedad de la conexión para habilitar el timeout de lectura en el socket. El valor es en milisegundos)

SQL Developer es el tipo de herramienta que tiene gran probabilidad de estar del otro lado de un firewall. Pero no parece haber ningún timeout interno en sqldeveloper, o por lo pronto, no funciona… SQL Developer para linux, pacientemente espera por el timeout de TCP. ¡Y no estamos hablando de milisegundos, sino más de 15 minutos!

Creo que esto estará bien para algunos, pero yo personalmente olvido lo que estaba planeando hacer ahi pasados luego de 15 minutos 🙂

El primer consejo más arriba, hace que SQL developer abra sockets TCP con setsockopt(SO_KEEPALIVE), y ese socket nunca estará ocioso por más de 30 segundos.
Y va a prevenir que el 99% de los firewalls cierren/bloqueen la conexión por inactividad. (la mayoría de los firewalls tienen políticas de tiempo límite a las conexiones ociosas, para prevenir muchos tipos de ataques DoS). Algunos firewalls podrían aun tratar los keepalive como “no-trafico real” y bloquear la conexión de todos modos.
Esto es similar a setear SQLNET.EXPIRE_TIME=x en sqlnet.ora del lado del server. Pero en este caso los keep alives vienen del lado del cliente.

El segundo consejo expuesto arriba, cubre el caso en el que la conexión aún se rompe (ya sea por firewall, o por desconexión de un cable).
Entonces seteamos el limite de TCP RTO a 5 en lugar de 15 que es el valor por defecto. Con RTO siendo un valor variable esto llevará el tiempo de TCP timeout debajo de los 30 seconds.
Puede causar alguna pérdida de tráfico de red en redes lentas, pero tiene que ser una red muy chota.

Fuente original (En inglés): https://alexeymoseyev.wordpress.com/2012/06/24/oracle-sql-developer-hangs-on-linux/