CentOS6.3でZenoss4.2.0をセットアップして、IPv6経由でリモートMySQL5.5.25aサーバーを監視しようとしています。ファイアウォールは監視サーバーに対して開いており、コマンドラインから正常に接続できます。
[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は有効なerrnoでさえありません。そしてもちろん Googleに負の数 することは不可能です。
ZMySqlUsernameとzMySqlPasswordを(複数回)チェックしましたが、正しい値を持っています。
角かっこを使用してIPv6アドレスを入力することも試みましたが、MySQLはZenoss内またはコマンドラインのどちらでもそれを好みません。
この問題の原因は何ですか?
私はついに諦めて、これを自分でデバッグしに行きました。
@SelivanovPavelの answer に基づいて、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
を開き、660行目あたりでAF_INET
を検索します。次に、次の変更を加えます。
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で修正されました であり、将来のリリースで利用可能になるはずです。
接続の試みがありますか?
tshark -i br200 -f "Host 2001:db8:81:2c::2"
tsharkは、パケットキャプチャプログラムWiresharkのコンソールバージョンです。
Zenossサービスユーザーがrootでない場合-彼のシェルからmysqlに接続してみてください:
su zenoss
mysql ...
Zenossログ([設定]> [デーモン])はどうですか?ログの詳細度を上げて(set logseverity = 30)、何が起こるかを確認してください。
このドキュメントは役に立つかもしれません: Troubleshooting_Zenoss
角かっこ[2001:470:...]またはipv6:[]で囲んでみてください。多くのパーサーは、テキストエントリとv6アドレスを区別できません。