分类: Mysql/postgreSQL
2010-03-05 11:17:47
出现这样的问题,已经是在使用mysql多年以后了。竟然第一次遇到,真是见鬼了。由于造成的现象就是无法远程连接数据库,所以定位问题上是相当麻烦的。
特征:相同dns下的mysql连接完全没有问题,意思应该是我的mysql服务如果在一台22.18的机子上,那我在22.19上去访问,那是没有问题地。但是如果我在其他的如1.111上去访问就不行了。但是曾经连上了的连接依然可以重连上,这是运气也是巧合了。
问题的实质:
mysql> show processlist
mysql> show status
通过这个查看mysql的各种状态。可以发现出现了很多大量的 Unauthenticated user 连接。这样的连接会阻塞整个mysql。这就是问题所在了。
然而这样的情况通常是在在服务器负载较重或者网络状态不稳定的情况造成的,这个应该引起这种问题某种原因吧。
这个状态是怎么产生的?这些未认证的用户来自哪里?
我们知道客户端连接mysql过程分为四个阶段:
Step 1: 第一阶段客户端连接服务器,如果不能连接成功,会得到这个错误:ERROR 2003 (HY000): Can't connect to MySQL server on '[host]' (111),这个阶段客户端没有提供任何其他的信息给服务器。
Step 2:服务器收到连接后返回一个握手信息,包括服务器的版本,线程号,服务器的地址和端口,客户端的地址和端口。在这个阶段,如果用show processlist查看,这个阶段还没有通过认证,但是客户端已经连接到服务器。如果这个进程发生问题,就会处于未认证用户的状态。通常这个错误都是由于DNS引起, DNS not resolving properly, which the skip-name-resolve option will help with.
有可能是/etc/resolv.conf 中的IP无法访问
Step 3:第三阶段,客户端发送用户名和密码的认证信息,以及还有默认的数据库,如果客户端没有发送正确的信息,或者在connect_timeout时间段内没能发回认证信息
,服务器就会断开连接.
Step 4: 服务器认证,根据认证结果返回是否通过认证的结果,如果认证未通过,返回错误:ERROR 1045 (28000): Access denied for user 'user'@'host' (using password: [YES/NO])
解决问题的办法,linux下和windows下虽然问题一样,处理方式不同,网上大多会是linux下的解决方法。我只保留我看的懂的方法了,就是在启动参数上添加 --skip-name-resolve 选项,禁止域名解析。
问题还真的解决了。甚喜!