Ошибка MySQL: (2003, «Не удается подключиться к серверу MySQL в 2001 году: db8: 81: 2c :: 2» (-9) »)

15

Я пытаюсь настроить Zenoss 4.2.0 на CentOS 6.3 для мониторинга удаленного сервера MySQL 5.5.25a через IPv6. Брандмауэр открыт для сервера мониторинга, и я могу нормально подключиться из командной строки:

[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)

Zenoss, однако, генерирует событие «Нет данных о производительности из плагина», детали которого жалуются на то, что он не может подключиться к серверу:

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

Насколько я знаю, -9 даже не является действительной ошибкой. И, конечно, невозможно гуглить отрицательное число .

введите описание изображения здесь

Я проверил zMySqlUsername и zMySqlPassword - более одного раза - и они имеют правильные значения.

Я также попытался ввести адрес IPv6 в квадратных скобках, но MySQL это не нравится ни в Zenoss, ни в командной строке.

В чем причина этой проблемы?

Майкл Хэмптон
источник
Если ничего не помогает, вы не можете вернуться к IPv4?
Джон Гарденье
@JohnGardeniers Иногда. Но многие из наблюдаемых машин не имеют глобальных IPv4-адресов, поэтому потребуется прокси Zenoss. Среди прочего я пытаюсь отойти от этого.
Майкл Хэмптон
Хорошо, я просто подумал, что это может быть вариант, особенно с IPv6, который является настолько неполным или несовершенным во многих продуктах.
Джон Гарденье

Ответы:

11

Я наконец сдался и пошел отлаживать это сам.

Основываясь на ответе @ SelivanovPavel, я включил отладку zencommandи ждал, и, конечно же, ZenPack терпел неудачу.

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 

Поэтому я покопался в ZenPack и обнаружил, что он импортирует (очевидно, старую версию) pymysqlиз /opt/zenoss/lib/python.

При тестировании из командной строки python я обнаружил, откуда выдается исключение:

>>> 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)")

И, осмотрев connections.pyэту общую окрестность, я с ужасом обнаружил, что она пытается открыть AF_INETсокет, и нигде не было кода для открытия AF_INET6сокета. Бум, мгновенный провал.

Текущая версия pymysqlтакже, кажется, содержит этот недостаток; нет поддержки IPv6 вообще.

Таким образом, «ответ», который я собираюсь исправить pymysql. Не так, как я хотел провести свой день.

Этот неприятный хакер заставляет все работать (хотя вам нужен Python 2.6). Откройте /opt/zenoss/lib/python/pymysql/connections.pyи найдите AF_INETоколо строки 660. Затем внесите следующие изменения:

                 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'

С тех пор это было исправлено в исходной версии pymysql и должно быть доступно в будущем выпуске.

Майкл Хэмптон
источник
5

Проверьте, есть ли попытки подключения:

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

tshark - консольная версия программы для сбора пакетов Wireshark.

Если пользователь сервиса zenoss не является пользователем root, попробуйте подключиться к mysql из его оболочки:

su zenoss
mysql ...

А как насчет логов Zenoss (Настройки> Демоны)? Попробуйте увеличить детализацию логов (установите logseverity = 30) и посмотрите, что получится.

Этот документ может быть полезным: Troubleshooting_Zenoss

Селиванов Павел
источник
Вы получаете награду, потому что вы подошли ближе, чем другой парень к источнику проблемы. Благодарю. :)
Майкл Хэмптон
3

Попробуйте заключить его в квадратные скобки [2001: 470: ...] или ipv6: []. Многие парсеры не могут различить текстовую запись и адрес v6.

rnxrx
источник
1
Был там, сделал это. MySQL, по крайней мере, хочет IP-адрес без скобок.
Майкл Хэмптон
2
Этот код ошибки может быть из библиотек, которые использует Zenoss, а не из самого mysql. Это написано в основном на Python, если я правильно помню, так что это может быть место для поиска подсказки.
rnxrx
1
Если мне придется копаться в исходном коде, я отвечу на свой вопрос. Опять таки. :)
Майкл Хэмптон
3
Не в этом ли прелесть открытого кода? Мы все можем исправить наши собственные ошибки <шучу>. Эй, еще одна мысль. Что если вы установите стандартное имя хоста, которое будет разрешено только AAAA, а затем будет использовать это имя хоста вместо необработанного IP?
rnxrx