mysql連接很慢,登陸到服務器上查看mysql日志:
IP address 'XX.XX.XX.XX' has been resolved to the host name 'XX.XX.XX.XX.ro.ovo.sc', which resembles IPv4-address itself.


原因是由於mysql對連接的客戶端進行DNS反向解析。
有2種解決辦法:
1,把client的ip寫在mysql服務器的/etc/hosts文件里,隨便給個名字就可以了。
2,在 my.cnf 中加入 –skip-name-resolve 。
對於第一種方法比較笨,也不實用,那么 skip-name-resolve 選項可以禁用dns解析,但是,這樣不能在mysql的授權表中使用主機名了,只能使用IP。
我理解mysql是這樣來處理客戶端解析過程的,
1,當mysql的client連過來的時候,服務器會主動去查client的域名。
2,首先查找 /etc/hosts 文件,搜索域名和IP的對應關系。
3,如果hosts文件沒有,則查找DNS設置,如果沒有設置DNS服務器,會立刻返回失敗,就相當於mysql設置了skip-name-resolve參數,如果設置了DNS服務器,就進行反向解析,直到timeout。



所謂反向解析是這樣的:
mysql接收到連接請求后,獲得的是客戶端的ip,為了更好的匹配mysql.user里的權限記錄(某些是用hostname定義的)。
如果mysql服務器設置了dns服務器,並且客戶端ip在dns上並沒有相應的hostname,那么這個過程很慢,導致連接等待。
 

添加skip-name-resolve以后就跳過着一個過程了。

官方的解釋

How MySQL
uses DNS When a new thread connects to mysqld, mysqld will
spawn a new thread to handle the request. This thread will first check
if the hostname is in the hostname cache. If not the thread will call
gethostbyaddr_r() and gethostbyname_r() to resolve the hostname. If
the operating system doesn’t support the above thread-safe calls, the
thread will lock a mutex and call gethostbyaddr() and gethostbyname()
instead. Note that in this case no other thread can resolve other
hostnames that is not in the hostname cache until the first thread is
ready. You can disable DNS host lookup by starting mysqld with
–skip-name-resolve. In this case you can however only use IP names in
the MySQL privilege tables. If you have a very slow DNS and many
hosts, you can get more performance by either disabling DNS lookop
with –skip-name-resolve or by increasing the HOST_CACHE_SIZE define
(default: 128) and recompile mysqld. You can disable the hostname
cache with –skip-host-cache. You can clear the hostname cache with
FLUSH HOSTS or mysqladmin flush-hosts. If you don’t want to allow
connections over TCP/IP, you can do this by starting mysqld with
–skip-networking.

注意:在增加該配置參數后,mysql的授權表中的host字段就不能夠使用域名而只能夠使用 ip地址了,因為這是禁止了域名解析的結果。