MySQL访问控制实现原理
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访问控制实现原理的更多相关文章
- MYSQL索引结构原理、性能分析与优化
[转]MYSQL索引结构原理.性能分析与优化 第一部分:基础知识 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里, 不用一页一页 ...
- MySQL主从同步原理 部署【转】
一.主从的作用:1.可以当做一种备份方式2.用来实现读写分离,缓解一个数据库的压力二.MySQL主从备份原理master 上提供binlog ,slave 通过 I/O线程从 master拿取 bin ...
- MySQL InnoDB 索引原理
本文由 网易云发布. 作者:范鹏程,网易考拉海购 InnoDB是 MySQL最常用的存储引擎,了解InnoDB存储引擎的索引对于日常工作有很大的益处,索引的存在便是为了加速数据库行记录的检索.以下是 ...
- 你的MySQL服务器开启SSL了吗?SSL在https和MySQL中的原理思考
最近,准备升级一组MySQL到5.7版本,在安装完MySQL5.7后,在其data目录下发现多了很多.pem类型的文件,然后通过查阅相关资料,才知这些文件是MySQL5.7使用SSL加密连接的.本篇主 ...
- 数据库MySQL 之 索引原理与慢查询优化
数据库MySQL 之 索引原理与慢查询优化 浏览目录 索引介绍方法类型 聚合索引辅助索引 测试索引 正确使用索引 组合索引 注意事项 查询计划 慢查询日志 大数据量分页优化 一.索引介绍方法类型 1. ...
- MySQL主从复制异步原理以及搭建
MySQL主从复制的原理: 1.首先,MySQL主库在事务提交时会把数据变更作为时间events记录在二进制日志文件binlog中:MySQL主库上的sync_binlog参数控制Binlog日志以什 ...
- MySQL Optimization 优化原理
MySQL Optimization 优化原理 MySQL逻辑架构 如果能在头脑中构建一幅MySQL各组件之间如何协同工作的架构图,有助于深入理解MySQL服务器.下图展示了MySQL的逻辑架构图. ...
- MySql 缓存查询原理与缓存监控 和 索引监控
MySql缓存查询原理与缓存监控 And 索引监控 by:授客 QQ:1033553122 查询缓存 1.查询缓存操作原理 mysql执行查询语句之前,把查询语句同查询缓存中的语句进行比较,且是按字节 ...
- MySQL 储存过程-原理、语法、函数详细说明
Mysql储存过程是一组为了完成特定功能的SQL语句集,经过编译之后存储在数据库中,当需要使用该组SQL语句时用户只需要通过指定储存过程的名字并给定参数就可以调用执行它了,简而言之就是一组已经写好的命 ...
随机推荐
- java泛型探索——介绍篇
1. 泛型出现前后代码对比 先来看看泛型出现前,代码是这么写的: List words = new ArrayList(); words.add("Hello "); words. ...
- redis的安装部署启动停止<17.3.21已更新>
--------------------------------------------------------- 启动redis时使用下面两条命令: redis-server /etc/redis. ...
- 计算facebook sdk需要的key hashes
1. 下载openssl,在C盘创建openssl文件夹,解压下载的zip到openssl文件夹. 2. 找到debug.keystore. windows下在C:\Users\用户名\.androi ...
- VR全景智慧城市-梦幻城市降临
有人说,创业分为两种,一种是富创业,一种是穷创业! 什么是富创业呢?就是拿钱砸,我觉得这种说法有点荒唐,为什么创业,因为没钱才会去创业,有钱的那不叫创业的,那是拿钱投资点项目. 看看老一辈的富豪,不都 ...
- Tomcat8-源码编译及开发
前言 下载Tomcat8源码进行分析,最好的方式,可以编译及运行,从网上查询了很多方式,总是不能完整的运行,由于本人采用idea编辑器,所以喜欢maven的方式,所以综合了网上的多种方案,最终可以在i ...
- 第 4 章 MySQL 安全管理
前言 对于任何一个企业来说,其数据库系统中所保存数据的安全性无疑是非常重要的,尤其是公司的有些商业数据,可能数据就是公司的根本,失去了数据的安全性,可能就是失去了公司的一切.本章将针对 MySQL 的 ...
- CMT2300 收发一体 SUB 1G 支持灵活选频
CMT2300A 是一款超低功耗,高性能,适用于各种140 至1020 MHz 无线应用的OOK,(G)FSK 射频收发器.它是CMOSTEK NextGenRFTM 射频产品线的一部分,这条产品线包 ...
- 搭建本地 Registry - 每天5分钟玩转 Docker 容器技术(20)
Docker Hub 虽然非常方便,但还是有些限制,比如: 需要 internet 连接,而且下载和上传速度慢. 上传到 Docker Hub 的镜像任何人都能够访问,虽然可以用私有 reposito ...
- jmeter跨线程组传值
在测试过程中,有时候需要jmeter跨线程组传值,jmeter本身又不具备此功能,那么,又该如何实现呢? 其实,我们可以通过BeanShell去实现. 实现过程如下: 1.线程组A中,使用正则表达式提 ...
- poi合并单元格同时导出excel
poi合并单元格同时导出excel POI进行跨行需要用到对象HSSFSheet对象,现在就当我们程序已经定义了一个HSSFSheet对象sheet. 跨第1行第1个到第2个单元格的操作为 sheet ...