最近发现网站访问速度变慢,有十几秒左右的延迟,跟踪代码发现sql查询非常快。查询mysql日志文件发现大量警告日志:
[Warning] IP address 'x,x,x,x' could not be resolved: Temporary failure in name resolution. IP是本机的外网地址
在mysql网站上找到一篇文章
http://dev.mysql.com/doc/refman/5.5/en/host-cache.html
文章主题:
8.12.6.2 DNS Lookup Optimization and the Host Cache
127.0.0.1
or
::1
), or for connections established using a Unix socket file, named pipe, or shared memory.
For each new client connection, the server uses the client IP address to check whether the client host name is in the host cache. If not, the server attempts to resolve the host name. First, it resolves the IP address to a host name and resolves that host name back to an IP address. Then it compares the result to the original IP address to ensure that they are the same. The server stores information about the result of this operation in the host cache. If the cache is full, the least recently used entry is discarded.
The server performs host name resolution using the thread-safe gethostbyaddr_r()
and gethostbyname_r()
calls if the operating system supports them. Otherwise, the thread performing the lookup locks a mutex and callsgethostbyaddr()
and gethostbyname()
instead. In this case, no other thread can resolve host names that are not in the host cache until the thread holding the mutex lock releases it.
大致意思客户端host过来后首选会检测host cache中有没有,否则就要通过gethostbyaddr_r()
和ethostbyname_r()来解析主机,这两个方法都是阻塞的,有互斥锁。
The server uses the host cache for several purposes:
-
By caching the results of IP-to-host name lookups, the server avoids doing a DNS lookup for each client connection. Instead, for a given host, it needs to perform a lookup only for the first connection from that host.
-
The cache contains information about errors that occur during the connection process. Some errors are considered “blocking.” If too many of these occur successively from a given host without a successful connection, the server blocks further connections from that host. The
max_connect_errors
system variable determines the number of permitted errors before blocking occurs. See Section B.5.2.6, “Host 'host_name' is blocked”.
max_connect_errors所设置的值时,就会发生阻塞
看到这里就不难明白为什么网站会变慢了
找到了原因,后面就不贴原文了,下面是讲的解决方法
1.可以通过
FLUSH HOSTS命令或 mysqladmin flush-hosts command来解锁
2.启动mysql时添加
--skip-host-cache参数选项,关闭host cache,默认是开启的。
添加
--skip-name-resolve
启动选项,关闭DNS解析,这样的话用户只能通过IP地址来连接数据库,分配权限时要注意,以前grant的权限也要进行修改。