MySQL访问控制实现原理

MySQL 访问控制实际上由两个功能模块共同组成,从第一篇的第二章架构组成中可以看
到,一个是负责 “看守 MySQL 大门”的用户管理模块,另一个就是负责监控来访者每一个动
作的访问控制模块。用户管理模块决定造访客人能否进门,而访问控制模块则决定每个客人
进门能拿什么不能拿什么。下面是一张 MySQL 中实现访问控制的简单流程图(见图 4-2):

1、 用户管理
我们先看看用户管理模块是如何工作的。在 MySQL 中,用户访问控制部分的实现比较简
单,所有授权用户都存放在一个系统表中: mysql.user,当然这个表不仅仅存放了授权用户
的基本信息,还存放有部分细化的权限信息。用户管理模块需要使用的信息很少,主要就是
Host,User,Password 这三项,都在 mysql.user 表中,如下:
sky@localhost : (none) 12:35:04> USE mysql;
Database changed
sky@localhost : mysql 12:35:08> DESC user;
+---------------+--------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------------+------+-----+---------+-------+
| Host | char(60) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Password | char(41) | NO | | | |
... ...
+---------------+--------------------+------+-----+---------+-------+
一个用户要想访问 MySQL,至少需要提供上面列出的这三项数据,MySQL 才能判断是否
该让他 “进门”。这三项实际上由量部分组成:访问者来源的主机名(或者主机 IP 地址信息 )
和访问者的来访 “暗号”(登录用户名和登录密码),这两部分中的任何一个没有能够匹配上
都无法让看守大门的用户管理模块乖乖开门。其中 Host 信息存放的是 MySQL 允许所对应的
User 的信任主机,可以是某个具体的主机名(如: mytest)或域名(如:www.domain.com),
也可以是以“%”来充当通配符的某个域名集合(如:%.domain.com);也可以是一个具体的
IP 地址(如:1.2.3.4),同样也可以是存在通配符的域名集合(如:1.2.3.%);还可以用“%”
来代表任何主机,就是不对访问者的主机做任何限制。如以下设置:
root@localhost : mysql 01:18:12> SELECT host,user,password FROM user ORDER BY
user;
+--------------------+------+-------------------------------------------+
| host | user | password |
+--------------------+------+-------------------------------------------+
| % | abc | |
| *.jianzhaoyang.com | abc | |
| localhost | abc | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
| 1.2.3.4 | abc | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
| 1.2.3.* | def | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
| % | def | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
| localhost | def | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
... ...
+--------------------+------+-------------------------------------------+
但是这里有一个比较特殊的访问限制,如果要通过 localhost 访问的话,必须要有一条
专门针对 localhost 的授权信息,即使不对任何主机做限制也不行。如下例所示,存在 def@%
的用户设置,但是如果不使用-h 参数来访问,则登录会被拒绝,因为 mysql 在默认情况下
会连接 localhost:
sky@sky:~$ mysql -u def -p
Enter password:
ERROR 1045 (28000): Access denied for user 'def'@'localhost' (using
password: YES)
但是当通过-h 参数,明确指定了访问的主机地址之后就没问题了,如下:
sky@sky:~$ mysql -u def -p -h 127.0.0.1
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 17
Server version: 5.0.51a-log Source distribution
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
def@127.0.0.1 : (none) 01:26:04>
如果我们有一条 localhost 的访问授权则可以不使用-h 参数来指定登录 host 而连接默
认的 localhost:
sky@sky:~$ mysql -u abc -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 18
Server version: 5.0.51a-log Source distribution
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
abc@localhost : (none) 01:27:19> exit
Bye
如果 MySQL 正在运行之中的时候,我们对系统做了权限调整,那调整之后的权限什么时
候会生效呢?
我们先了解何时 MySQL 存放于内存结构中的权限信息被更新:FLUSH PRIVILEGES 会强
行让 MySQL 更新 Load 到内存中的权限信息; GRANT、REVOKE 或者 CREATE USER 和 DROP USER
操作会直接更新内存中俄权限信息;重启 MySQL 会让 MySQL 完全从 grant tables 中读取权
限信息。
那内存结构中的权限信息更新之后对已经连接上的用户何时生效呢?
对于 Global Level 的权限信息的修改,仅仅只有更改之后新建连接才会用到,对于已
经连接上的 session 并不会受到影响。而对于 Database Level 的权限信息的修改,只有当
客户端请求执行了“USE database_name”命令之后,才会在重新校验中使用到新的权限信
息。所以有些时候如果在做了比较紧急的 Global 和 Database 这两个 Level 的权限变更之后 ,
可能需要通过“KILL”命令将已经连接在 MySQL 中的 session 杀掉强迫他们重新连接以使
用更新后的权限。对于 Table Level 和 Column Level 的权限,则会在下一次需要使用到该
权限的 Query 被请求的时候生效,也就是说,对于应用来讲,这两个 Level 的权限,更新之
后立刻就生效了,而不会需要执行“KILL”命令。
2、 访问控制
当客户端连接通过用户管理模块的验证,可连接上 MySQL Server 之后,就会发送各种
Query 和 Command 给 MySQL Server,以实现客户端应用的各种功能。当 MySQL 接收到客户
端的请求之后,访问控制模块是需要校验该用户是否满足提交的请求所需要的权限。权限校
验过程是从最大范围的权限往最小范围的权限开始依次校验所涉及到的每个对象的每个权
限。
在验证所有所需权限的时候, MySQL 首先会查找存储在内存结构中的权限数据,首先查
找 Global Level 权限,如果所需权限在 Global Level 都有定义(GRANT 或者 REVOKE),
则完成权限校验(通过或者拒绝),如果没有找到所有权限的定义,则会继续往后查找
Database Level 权限,进行 Global Level 未定义的所需权限的校验,如果仍然没有能够
找到所有所需权限的定义,MySQL 会继续往更小范围的权限定义域查找,也就是 Table
Level,最后则是 Column Level 或者 Routine Level。
下面我们就以客户端通过 abc@localhost 连接后请求如下 Query 我为例:
SELECT id,name FROM test.t4 where status = 'deleted';

在前面我们了解到 MySQL 的 grant tables 有 mysql.user,mysql.db,mysql.host,
mysql.table_priv 和 mysql.column_priv 这五个,我想出了 mysql.host 之外的四个都是非
常容易理解的,每一个表针对 MySQL 中的一种逻辑对象,存放某一特定 Level 的权限,唯独
mysql.host 稍有区别。我们现在就来看看 mysql.host 权限表到底在 MySQL 的访问控制中充
当了一个什么样的角色呢?
mysql.host 在 MySQL 访问控制模块中所实现的功能比较特殊,和其他几个 grant tables
不太一样。首先是 mysql.host 中的权限数据不是(也不能)通过 GRANT 或者 REVOKE 来授予
或者去除,必须通过手工通过 INSERT、UPDATE 和 DELETE 命令来修改其中的数据。其次是
其中的权限数据无法单独生效,必须通过和 mysql.db 权限表的数据一起才能生效。而且仅
当 mysql.db 中存在不完整(某些场景下的特殊设置)的时候,才会促使访问控制模块再结
合 mysql.host 中查找是否有相应的补充权限数据实现以达到权限校验的目的,就比如上图
中所示。在 mysql.db 中无法找到满足权限校验的所有条件的数据(db.User = 'abc' AND
db.host = 'localhost' AND db.Database_name = 'test'),则说明在 mysql.db 中无法完
成权限校验,所以也不会直接就校验 db.Select_priv 的值是否为'Y'。但是 mysql.db 中有
db.User = 'abc' AND db.Database_name = 'test' AND db.host = '' 这样一条权限信息
存在,大家可能注意到了这条权限信息中的 db.host 中是空值,注意是空值而不是'%'这个
通配符哦。当 MySQL 注意到有这样一条权限信息存在的时候,就该是 mysql.host 中所存放
的权限信息出场的时候了。这时候,MySQL 会检测 mysql.host 中是否存在满足如下条件的
权限信息:host.Host = 'localhost' AND host.Db = 'test'。如果存在,则开始进行
Select_priv 权限的校验。由于权限信息存在于 mysql.db 和 mysql.host 两者之中,而且是
两者信息合并才能满足要求,所以 Select_priv 的校验也需要两表都为'Y'才能满足要求,
通过校验。
我们已经清楚,MySQL 的权限是授予“username@hostname”的,也就是说,至少需要
用户名和主机名二者才能确定一个访问者的权限。又由于 hostname 可以是一个含有通配符
的域名,也可以是一个含有通配符的 IP 地址段。那么如果同一个用户有两条权限信息,一
条是针对特定域名的,另外一个是含有通配符的域名,而且前者属于后者包含。这时候 MySQL
如何来确定权限信息呢?实际上 MySQL 永远优先考虑更精确范围的权限。在 MySQL 内部会按
照 username 和 hostname 作一个排序,对于相同 username 的权限,其 host 信息越接近访问
者的来源 host,则排序位置越靠前,则越早被校验使用到。而且, MySQL 在权限校验过程中 ,
只要找到匹配的权限之后,就不会再继续往后查找是否还有匹配的权限信息,而直接完成校
验过程。
大家应该也看到了在 mysql.user 这个权限表中有 max_questions,max_updates,
max_connections,max_user_connections 这四列,前面三列是从 MySQL4.0.2 版本才开始
有的,其功能是对访问用户进行每小时所使用资源的限制,而最后的 max_user_connections
则是从 MySQL5.0.3 版本才开始有的,他和 max_connections 的区别是限制耽搁用户的连接
总次数,而不是每小时的连接次数。而要使这四项限制生效,需要在创建用户或者给用户授
权的时候加上以下四种子句:
max_questions : WITH MAX_QUERIES_PER_HOUR n;
max_updates : WITH MAX_UPDATES_PER_HOUR n;
max_connections : WITH MAX_CONNECTIONS_PER_HOUR n;
max_user_connections: MAX_USER_CONNECTIONS。
四个子句可以同时使用,如:
“ WITH MAX_QUERIES_PER_HOUR 5000 MAX_CONNECTIONS_PER_HOUR 10
MAX_USER_CONNECTIONS 10000”。

MySQL访问控制实现原理的更多相关文章

  1. MYSQL索引结构原理、性能分析与优化

    [转]MYSQL索引结构原理.性能分析与优化 第一部分:基础知识 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里, 不用一页一页 ...

  2. MySQL主从同步原理 部署【转】

    一.主从的作用:1.可以当做一种备份方式2.用来实现读写分离,缓解一个数据库的压力二.MySQL主从备份原理master 上提供binlog ,slave 通过 I/O线程从 master拿取 bin ...

  3. MySQL InnoDB 索引原理

    本文由  网易云发布. 作者:范鹏程,网易考拉海购 InnoDB是 MySQL最常用的存储引擎,了解InnoDB存储引擎的索引对于日常工作有很大的益处,索引的存在便是为了加速数据库行记录的检索.以下是 ...

  4. 你的MySQL服务器开启SSL了吗?SSL在https和MySQL中的原理思考

    最近,准备升级一组MySQL到5.7版本,在安装完MySQL5.7后,在其data目录下发现多了很多.pem类型的文件,然后通过查阅相关资料,才知这些文件是MySQL5.7使用SSL加密连接的.本篇主 ...

  5. 数据库MySQL 之 索引原理与慢查询优化

    数据库MySQL 之 索引原理与慢查询优化 浏览目录 索引介绍方法类型 聚合索引辅助索引 测试索引 正确使用索引 组合索引 注意事项 查询计划 慢查询日志 大数据量分页优化 一.索引介绍方法类型 1. ...

  6. MySQL主从复制异步原理以及搭建

    MySQL主从复制的原理: 1.首先,MySQL主库在事务提交时会把数据变更作为时间events记录在二进制日志文件binlog中:MySQL主库上的sync_binlog参数控制Binlog日志以什 ...

  7. MySQL Optimization 优化原理

    MySQL Optimization 优化原理 MySQL逻辑架构 如果能在头脑中构建一幅MySQL各组件之间如何协同工作的架构图,有助于深入理解MySQL服务器.下图展示了MySQL的逻辑架构图. ...

  8. MySql 缓存查询原理与缓存监控 和 索引监控

    MySql缓存查询原理与缓存监控 And 索引监控 by:授客 QQ:1033553122 查询缓存 1.查询缓存操作原理 mysql执行查询语句之前,把查询语句同查询缓存中的语句进行比较,且是按字节 ...

  9. MySQL 储存过程-原理、语法、函数详细说明

    Mysql储存过程是一组为了完成特定功能的SQL语句集,经过编译之后存储在数据库中,当需要使用该组SQL语句时用户只需要通过指定储存过程的名字并给定参数就可以调用执行它了,简而言之就是一组已经写好的命 ...

随机推荐

  1. .net数据统计系统设计(中小型)

    近一年多没在博客园写东西了,从换公司后就一直努力学习公司的框架和业务.而今接手一个电商数据统计项目,在博客园搜索统计项目解决方案却一无所获,最终自己设计并在开发的过程中持续更新,希望可以和大家一起交流 ...

  2. 单片机IAP学习

    1.IAP是什么--简介 IAP是In Application Programming的首字母缩写,IAP是用户自己的程序在运行过程中对User Flash的部分区域进行烧写,目的是为了在产品发布后可 ...

  3. 谷歌IAP:skusBundle array associated with key ITEM_ID_LIST cannot contain more than 20 items.

    这几天在接谷歌的支付,在拉谷歌商品列表的时候转菊花,长时间不返回(querySkuDetails),一开始以为因为IAP有key不对导致的,查了下发现没有问题. 再看logcat,发现了这行: Inp ...

  4. JEESZ分布式框架简介

    声明:该框架面向企业,是大型互联网分布式企业架构,后期会介绍Linux上部署高可用集群项目. 项目基础功能截图(自提供了最小部分) 介绍 1.      项目核心代码结构截图 <modules& ...

  5. Mysql5.7忘记root密码及修改root密码的方法

    Mysql 安装成功后,输入 mysql --version 显示版本如下 mysql Ver 14.14 Distrib 5.7.13-6, for Linux (x86_64) using 6.0 ...

  6. Sampling Distributions and Central Limit Theorem in R(转)

    The Central Limit Theorem (CLT), and the concept of the sampling distribution, are critical for unde ...

  7. Spring Boot 负载均衡之外置session状态保存

    在使用spring boot做负载均衡的时候,多个app之间的session要保持一致,这样负载到不同的app时候,在一个app登录之后,而打到另外一台服务器的时候,session丢失. 常规的解决方 ...

  8. 安装lnmp集成环境

    具体配置看原文,不重新复述: 原文:https://lnmp.org/install.html 因为配置数据库主从,需要保持两台mysql数据库服务器的mysql版本号一致,所以又重新装了一次..重新 ...

  9. 全景智慧掌上城,飞入寻常百姓家——VR全景智慧城市

    随着腾讯和阿里陆续将AR技术加入到新年抢红包大战之中,人们对于VR.AR未来的应用空间又多了一些想象.同传统的基于二维元素的抢红包不同,借助VR.AR的技术能够让用户获得一种更加真切的体验,这种体验相 ...

  10. [速成]了解一致性hash算法

    定义 一致性hash算法,在维基百科的定义是: Consistent hashing is a special kind of hashing such that when a hash table ...