当 MySQL 以 skip-name-resolve 模式启动时如何使用 grant 命令
本文介绍了 MySQL
中 skip-name-resolve
参数对连接的优化作用,随之而来的权限表仅可使用 IP
的限制,以及如何在无法提前确定 IP
的情况下使用 grant
命令搭配通配符 %
进行授权。
背景介绍
在 MySQL
新建一个用户 exporter
给 mysqld-exporter
使用,然后通过 grant
命令授予该用户部分权限。执行命令如下:
1 | CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'XXXXXXXX' WITH MAX_USER_CONNECTIONS 3; |
在执行时提示“这次 grant
需要关闭 skip-name-resolve
参数然后重启 MySQL
才能生效”。
1 | 0 row(s) affected, 1 warning(s): 1285 MySQL is started in --skip-name-resolve mode; you must restart it without this switch for this grant to work |
本着默认的参数不随便修改的想法,我们来看一看 skip-name-resolve
参数究竟有什么用。
skip-name-resolve 的作用
MySQL
在启动时默认使用 skip-name-resolve
参数。顾名思义,该参数用于跳过 MySQL
的 DNS
解析。关于 MySQL
是如何使用 DNS
的,官方文档是这样介绍的:
当一个新线程连接到 mysqld
,mysqld
会生成一个新线程去处理该请求。该线程首先检查主机名是否在主机名缓存中,如果没有那么该线程会调用 gethostbyaddr_r()
和 gethostbyname_r()
来解析主机名。如果操作系统不支持上述线程安全的调用,那么该线程会加锁然后调用 gethostbyaddr()
和 gethostbyname()
。这种情况下,在第一个线程准备好之前,没有其他线程可以解析不在主机名缓存中的其他主机名。MySQL
允许通过 skip-name-resolve
参数禁用 DNS
解析,但是如果禁用的话,在 MySQL
的权限表中就只能使用 IP
。
获取
IP
和主机名可以用于在权限表中匹配权限,如果禁用DNS
解析,在权限表中只能使用IP
也就理所当然了。
官方建议如果你的 DNS
解析非常慢或者你有非常多的主机,可以使用 skip-name-resolve
参数禁用 DNS
解析或者增加 HOST_CACHE_SIZE
(默认值:128
)并重新编译 mysqld
来获得更高的性能。以下文章的作者介绍了他们因为 MySQL
DNS
解析遇到的连接慢的问题:
因为缺乏对具体的
MySQL
代码实现的了解,所以没有办法对上述过程进行深入和准确的描述。在官方的表述中,根据IP
查询主机名和根据主机名查询IP
似乎都存在;但在查阅到的资料中,部分文章提到的一般是“反向解析”,也就是根据IP
查询主机名;但是更多的文章对这部分比较含糊其辞。
怎么使用 grant 命令
如果你并不考虑对特定用户多加限制,那么使用通配符 %
即可,它将允许从任意 IP
连接 MySQL
。
1 | CREATE USER 'exporter'@'%' IDENTIFIED BY 'XXXXXXXX' WITH MAX_USER_CONNECTIONS 3; |
但是在我的情况中,新建的用户是给 mysqld-exporter
获取 MySQL
的监控数据的,显然限制该用户的 IP
、连接数以及权限很有必要。可是如果使用的是 Docker
或者其他无法提前确定 IP
的环境怎么办呢?还是可以使用通配符 %
限制为仅某一 IP
范围可以访问。
1 | CREATE USER 'exporter'@'172.19.%.%' IDENTIFIED BY 'XXXXXXXX' WITH MAX_USER_CONNECTIONS 3; |