ข้อผิดพลาดของ 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 ไม่ได้เป็น errno ที่ถูกต้อง และแน่นอนมันเป็นไปไม่ได้ที่Google จำนวนลบ

ป้อนคำอธิบายรูปภาพที่นี่

ฉันได้ตรวจสอบ zMySqlUsername และ zMySqlPassword - มากกว่าหนึ่งครั้ง - และพวกเขามีค่าที่ถูกต้อง

ฉันได้ลองป้อนที่อยู่ IPv6 ด้วยเครื่องหมายวงเล็บ แต่ MySQL ไม่ชอบเลยทั้งใน Zenoss หรือในบรรทัดคำสั่ง

สาเหตุของปัญหานี้คืออะไร?


หากสิ่งอื่นล้มเหลวคุณจะไม่สามารถย้อนกลับไปใช้ IPv4 ได้หรือไม่
จอห์น Gardeniers

@JohnGardeniers บางครั้ง แต่เครื่องจำนวนมากที่ต้องตรวจสอบไม่มีที่อยู่ IPv4 ทั่วโลกดังนั้นจึงต้องมีพร็อกซี Zenoss เหนือสิ่งอื่นใดฉันพยายามจะหลีกหนีจากสิ่งนั้น
Michael Hampton

ตกลงฉันแค่คิดว่ามันอาจเป็นตัวเลือกโดยเฉพาะอย่างยิ่งกับ IPv6 ที่ไม่สมบูรณ์หรือไม่สมบูรณ์ในผลิตภัณฑ์จำนวนมาก
John Gardeniers

คำตอบ:


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 ไม่ใช่รูท - ลองเชื่อมต่อกับ mysql จากเชลล์:

su zenoss
mysql ...

สิ่งที่เกี่ยวกับบันทึก Zenoss (การตั้งค่า> Daemons) ลองเพิ่มการใช้คำฟุ่มเฟือยของล็อก (set logseverity = 30) และดูว่าเกิดอะไรขึ้น

เอกสารนี้อาจมีประโยชน์: การแก้ไขปัญหา _Zenoss


คุณได้รับรางวัลเพราะคุณเข้ามาใกล้กว่าผู้ชายคนอื่นในการหาสาเหตุของปัญหา ขอบคุณ :)
Michael Hampton

3

ลองวางในวงเล็บ [2001: 470: ... ] หรือ ipv6: [] ตัวแยกวิเคราะห์จำนวนมากไม่สามารถแยกความแตกต่างระหว่างการป้อนข้อความและที่อยู่ v6


1
เคยทำมาแล้ว อย่างน้อย MySQL ต้องการที่อยู่ IP โดยไม่ต้องวงเล็บ
Michael Hampton

2
รหัสข้อผิดพลาดนั้นอาจมาจากไลบรารีที่ Zenoss ใช้แทนที่จะเป็น mysql เอง มันเขียนไว้ใน Python เป็นส่วนใหญ่หากฉันจำได้ถูกต้องดังนั้นอาจเป็นสถานที่ที่จะมองหาคำใบ้
rnxrx

1
ถ้าฉันต้องขุดลงไปในซอร์สโค้ดฉันจะจบการตอบคำถามของตัวเอง อีกครั้ง :)
Michael Hampton

3
ความงามของโอเพ่นซอร์สไม่ใช่หรือ เราทุกคนสามารถแก้ไขข้อบกพร่องของตัวเอง <การเสนอราคา> เฮ้ - คิดอีกอย่าง ถ้าคุณตั้งค่าชื่อโฮสต์มาตรฐานที่แก้ไขเป็น AAAA แล้วใช้ชื่อโฮสต์นั้นแทน IP ดิบ
rnxrx
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.