5 rows in set (0.00 sec)
使用localhost登录时:
[root@Node5 mysql]# mysql -hlocalhost -uroot -p123
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 10.1.21-MariaDB Source distribution
Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> status
--------------
mysql Ver 15.1 Distrib 10.1.21-MariaDB, for Linux (x86_64) using readline 5.1
Connection id:8
Current database:
Current user:root@localhost
SSL:Not in use
Current pager:stdout
Using outfile:''
Using delimiter:;
Server:MariaDB
Server version:10.1.21-MariaDB Source distribution
Protocol version:10
Connection:Localhost via UNIX socket
Server characterset:utf8
Db characterset:utf8
Client characterset:utf8
Conn. characterset:utf8
UNIX socket:/tmp/mysql.sock
Uptime:2 min 39 sec
Threads: 1 Questions: 6 Slow queries: 0 Opens: 17 Flush tables: 1 Open tables: 11 Queries per second avg: 0.037
--------------
MariaDB [(none)]>
使用127.0.0.1时:
[root@Node5 mysql]# mysql -h127.0.0.1 -p123
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 12
Server version: 10.1.21-MariaDB Source distribution
Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> status
--------------
mysql Ver 15.1 Distrib 10.1.21-MariaDB, for Linux (x86_64) using readline 5.1
Connection id:12
Current database:
Current user:root@localhost
SSL:Not in use
Current pager:stdout
Using outfile:''
Using delimiter:;
Server:MariaDB
Server version:10.1.21-MariaDB Source distribution
Protocol version:10
Connection:127.0.0.1 via TCP/IP
Server characterset:utf8
Db characterset:utf8
Client characterset:utf8
Conn. characterset:utf8
TCP port:3306
Uptime:11 min 40 sec
Threads: 2 Questions: 31 Slow queries: 0 Opens: 17 Flush tables: 1 Open tables: 11 Queries per second avg: 0.044
--------------
我们可以看到虽然用的是不同的通信方式但密码都是使用"root"@"localhost"的密码为什么会这样呢
基于以下原因MySQL服务端会在内存中维护着一份host信息 包括三部分IP主机名和错误信息。主要用于非本地TCP连接。
1. 通过在第一次建立连接时缓存IP和host name的映射关系同一主机的后续连接将直接查看host cache而不用再次进行DNS解析。
2. host cache中同样会包含IP登录失败的错误信息。可根据这些信息对这些IP进行相应的限制。
host cache的信息可通过performance_schema中host_cache表查看。
那么IP和host name的映射关系是如何建立的呢
1. 当有一个新的客户端连接进来时MySQL Server会为这个IP在host cache中建立一个新的记录包括IP主机名和client lookup validation flag分别对应host_cache表中的IPHOST和HOST_VALIDATED这三列。第一次建立连接因为只有IP没有主机名所以HOST将设置为NULLHOST_VALIDATED将设置为FALSE。
2. MySQL Server检测HOST_VALIDATED的值如果为FALSE它会试图进行DNS解析如果解析成功它将更新HOST的值为主机名并将HOST_VALIDATED值设为TRUE。如果没有解析成功判断失败的原因是永久的还是临时的如果是永久的则HOST的值依旧为NULL且将HOST_VALIDATED的值设置为TRUE后续连接不再进行解析如果该原因是临时的则HOST_VALIDATED依旧为FALSE后续连接会再次进行DNS解析。
另解析成功的标志并不只是通过IP获取到主机名即可这只是其中一步还有一步是通过解析后的主机名来反向解析为IP判断该IP是否与原IP相同如果相同才判断为解析成功才能更新host cache中的信息。
基于上面的总结下面谈谈 host cache的优缺点
缺点当有一个新的客户端连接进来时MySQL Server都要建立一个新的记录如果DNS解析很慢无疑会影响性能。如果被允许访问的主机很多也会影响性能这个与host_cache_size有关这个参数是5.6.5引入的。5.6.8之前默认是128,5.6.8之后默认是-1,基于max_connections的值动态调整。所以如果被允许访问的主机很多基于LRU算法先前建立的连接可能会被挤掉这些主机重新进来时会再次进行DNS查询。
优点通常情况下主机名是不变的而IP是多变的。如果一个客户端的IP经常变化那基于IP的授权将是一个繁琐的过程。因为你很难确定IP什么时候变化。而基于主机名只需一次授权。而且基于host cache中的失败信息可在一定程度上阻止外界的暴力破解***。
关于阻止外界的暴力破解***涉及到max_connect_errors参数默认为100官方的解释如下
If more than this many successive connection requests from a host are interrupted without a successful connection, the server blocks that host from further connections. 如果某个客户端的连接达到了max_connect_errors的限制将被禁止访问并提示以下错误
Host 'host_name' is blocked because of many connection errors.
Unblock with 'mysqladmin flush-hosts'
下面来模拟一下
首先设置max_connect_errors的值:
mysql> show variables like 'max_connect_errors';
+--------------------+-------+| Variable_name | Value |+--------------------+-------+| max_connect_errors | 100 |+--------------------+-------+1 row in set (0.00 sec)
mysql> set global max_connect_errors=2;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'max_connect_errors';
+--------------------+-------+| Variable_name | Value |+--------------------+-------+| max_connect_errors | 2 |+--------------------+-------+1 row in set (0.00 sec)
通过telnet模拟interrupted without a successful connection。
[root@mysql-slave1 ~]# telnet 192.168.244.145 3306Trying 192.168.244.145...
Connected to 192.168.244.145.
Escape character is '^]'.
N5.6.26-log
K]qA1nYT!w|+ZhxF1c#|kmysql_native_password^]!#08S01Got packets out of orderConnection closed by foreign host.