Erro no MySQL: (2003, “Não é possível conectar ao servidor MySQL em '2001: db8: 81: 2c :: 2' (-9)”)

15

Estou tentando configurar o Zenoss 4.2.0 no CentOS 6.3 para monitorar um servidor remoto MySQL 5.5.25a via IPv6. O firewall está aberto para o servidor de monitoramento e posso conectar-me bem na linha de comando:

[root@zenoss ~]# mysql -u zenoss -p -h 2001:db8:81:2c::2
...
mysql> SELECT USER(),CURRENT_USER();
+-----------------------------------------+-----------------------------------------+
| USER()                                  | CURRENT_USER()                          |
+-----------------------------------------+-----------------------------------------+
| zenoss@2001:db8:16:bf:5054:ff:fec0:f7a5 | zenoss@2001:db8:16:bf:5054:ff:fec0:f7a5 |
+-----------------------------------------+-----------------------------------------+
1 row in set (0.09 sec)

O Zenoss, no entanto, gera um evento "Nenhum dado de desempenho do plug-in" cujos detalhes reclamam que ele não pode se conectar ao servidor:

MySQL Error: (2003, "Can't connect to MySQL server on '2001:db8:81:2c::2' (-9)")

Até onde eu sei, -9 nem é um erro válido. E é claro que é impossível procurar um número negativo no Google .

insira a descrição da imagem aqui

Eu verifiquei zMySqlUsername e zMySqlPassword - mais de uma vez - e eles têm os valores corretos.

Também tentei digitar o endereço IPv6 entre colchetes, mas o MySQL não gosta disso, nem no Zenoss nem na linha de comando.

Qual é a causa desse problema?

Michael Hampton
fonte
Se tudo mais falhar, você não pode voltar ao IPv4?
John Gardeniers
@JohnGardeniers Às vezes. Porém, muitas das máquinas a serem monitoradas não possuem endereços IPv4 globais, portanto, um proxy Zenoss seria necessário. Entre outras coisas, estou tentando me afastar disso.
Michael Hampton
Ok, eu apenas pensei que poderia ser uma opção, especialmente com o IPv6 sendo tão incompleto ou imperfeito em muitos produtos.
John Gardeniers

Respostas:

11

Eu finalmente desisti e fui depurar esse eu mesmo.

Com base na resposta de @ SelivanovPavel zencommand, apareci depurando e esperei, e com certeza, o ZenPack estava falhando.

2012-08-16 18:16:14,092 INFO zen.zencommand: Datasource MySQL/mysql command: /opt/zenoss/ZenPacks/ZenPacks.zenoss.MySqlMonitor-2.2.0-py2.7.egg/ZenPacks/zenoss/MySqlMonitor/libexec/check_mysql_stats.py -H 2001:db8:81:2c::2 -p 3306 -u zenoss -w 'password' -g
2012-08-16 18:16:14,100 DEBUG zen.zencommand: Running /opt/zenoss/ZenPacks/ZenPacks.zenoss.MySqlMonitor-2.2.0-py2.7.egg/ZenPacks/zenoss/MySqlMonitor/libexec/check_mysql_stats.py
2012-08-16 18:16:14,544 DEBUG zen.zencommand: Datasource: mysql Received exit code: 1 Output: 'MySQL Error: (2003, "Can\'t connect to MySQL server on \'2001:db8:81:2c::2\' (-9)")\n'
2012-08-16 18:16:14,545 DEBUG zen.zencommand: Process MySQL/mysql stopped (1), 0.43 seconds elapsed 

Então, procurei no ZenPack e descobri que estava importando (uma versão aparentemente antiga) pymysqldo /opt/zenoss/lib/python.

Ao testar a partir da linha de comando python, descobri de onde a exceção estava sendo lançada:

>>> sys.path.insert(0, "/opt/zenoss/lib/python");
>>> import pymysql
>>> pymysql.install_as_MySQLdb()
>>> import MySQLdb
>>> self.conn = MySQLdb.connect(host="2001:db8:81:2c::2", port=3306, db='', user='zenoss', passwd='password')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/zenoss/lib/python/pymysql/__init__.py", line 93, in Connect
    return Connection(*args, **kwargs)
  File "/opt/zenoss/lib/python/pymysql/connections.py", line 504, in __init__
    self._connect()
  File "/opt/zenoss/lib/python/pymysql/connections.py", line 673, in _connect
    raise OperationalError(2003, "Can't connect to MySQL server on %r (%s)" % (self.host, e.args[0]))
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on '2001:db8:81:2c::2' (-9)")

E, ao inspecionar connections.pyaquela vizinhança geral, descobri, horrorizado, que estava tentando abrir um AF_INETsoquete, e não havia código em nenhum lugar para abrir um AF_INET6soquete. Crescimento, falha instantânea.

A versão atual do pymysqltambém parece conter essa deficiência; nenhum suporte IPv6 .

Então a "resposta" é que vou ter que consertar pymysql. Não é como eu queria passar minha tarde.

Esse pequeno truque desagradável faz as coisas funcionarem (embora você precise do Python 2.6). Abra /opt/zenoss/lib/python/pymysql/connections.pye procure pela AF_INETlinha 660. Em seguida, faça a seguinte alteração:

                 if DEBUG: print 'connected using unix_socket'
             else:
-                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-                t = sock.gettimeout()
-                sock.settimeout(self.connect_timeout)
-                sock.connect((self.host, self.port))
-                sock.settimeout(t)
+                sock = socket.create_connection((self.host, self.port), self.connect_timeout)
                 self.host_info = "socket %s:%d" % (self.host, self.port)
                 if DEBUG: print 'connected using socket'

Isso foi corrigido no pymysql upstream e deve estar disponível em uma versão futura.

Michael Hampton
fonte
5

Verifique, existem tentativas de conexão:

tshark -i br200 -f "host 2001:db8:81:2c::2"

tshark é a versão do console do programa de captura de pacotes Wireshark.

Se o usuário do serviço zenoss não for root - tente conectar-se ao mysql pelo shell:

su zenoss
mysql ...

E os logs do Zenoss (Configurações> Daemons)? Tente aumentar a verbosidade dos logs (defina logseverity = 30) e veja o que acontece.

Este documento pode ser útil: Troubleshooting_Zenoss

Selivanov Pavel
fonte
Você recebe a recompensa porque chegou mais perto do que o outro cara da fonte do problema. Obrigado. :)
Michael Hampton
3

Tente colocá-lo entre colchetes [2001: 470: ...] ou ipv6: []. Muitos analisadores não conseguem diferenciar entre uma entrada de texto e um endereço v6.

rnxrx
fonte
1
Estive lá, fiz isso. O MySQL, pelo menos, quer o endereço IP sem colchetes.
Michael Hampton
2
Esse código de erro pode ser das bibliotecas que o Zenoss está usando e não do próprio mysql. Está escrito principalmente em Python, se estou lembrando corretamente, para que possa ser um lugar para procurar uma dica.
Rnxrx
1
Se eu precisar pesquisar o código fonte, acabarei respondendo à minha própria pergunta. Novamente. :)
Michael Hampton
3
Não é essa a beleza do código aberto? Todos nós podemos consertar nossos próprios erros <kidding>. Ei - outro pensamento, no entanto. E se você configurasse um nome de host padrão que fosse resolvido apenas como AAAA e usasse esse nome de host em vez do IP bruto?
Rnxrx