1. 这章讨论如何管理账户
1.授权表 存储账户信息
2. 用于账号管理的语句
3.server 如何使用grant table 内容来控制客户端访问
34.1 用户账户管理:
MYSQL 访问控制系统使你能创建MYSQL账户和 每个账户能做什么。
在MYSQL里,账户的内容是取决于2个事情:
一个是用户名和主机名
当你连接到server时, 它检查不只是你制定的用户名,也是你要连接的主机。
一个账户可能设置单独的账户
在SQL语句里 需要账户名字,格式如下
'usr_name'@'host_name'格式。
几种类型的权限可以授权给账户。 根据用户使用的情况进行授权:
1. 一个账户只需要访问数据库的权限 那么直需要给SELECT 权限
2. 一个账户需要修改数据 那么需要给DELETE,INSERT和UPDATE权限
3.管理账户给PROCESS或则SUPER 权限用于查看客户端进程的活动和kill连接或者shutdown 权限来停止它。
MYSQL 服务器基于访问控制基于授权表。 这些表定义了MYSQL 账户和权限(他们持有的),
来管理他们的内容,使用语句比如CREATE USER,GRANT 和RWVOKE。
这些语句提供了一个接口到授权表 使你可以指定账户管理操作而不必要决定如何直接的修改表
MYSQL SERVER 决定了 执行相应的修改
西面的章节讨论授权表的内容 和各种各样的语句帮助你管理账户。
34.1.1 MYSQL支持的权限类型
你可以给出多种MYSQL 账户的权限,你可以grant 权限在不同的level(全局的或者只是特定的数据库,表和列).
比如, 你可以允许用户选择任何数据库的任何表通过授予select 权限在global level.
或者 你可以授权一个账户不是全局权限,但是给它完整的控制一个特定的数据库
允许账户来创建数据库和表,查询表 和添加记录 删除和修改
MYSQL 支持的权限在下面显示,第一列是管理权限 第2列是控制访问数据库的或者 存储在数据库的对象
管理权限
Privilege 该权限允许的操作
CREATE TEMPORARY TABLES 使用临时表用CREATE TABLE
CREATE USER 创建,删除和rename 账户
FILE 使用语句来读写服务器主机上的文件
LOCK TABLES 显示的lock table
PROCESS 查看 process(thread)活动情况
RELOAD 使用FLUSH 和RESET
REPLICATION CLIENT 询问server 关于复制主机的信息
REPLICATION SLAVE 作为一个复制的slave
SHOW DATABASES 列出所有的数据库
SHUTDOWN 关闭数据库
SUPER 管理员权限
数据库访问权限
权限 权限允许的操作
ALTER ALTER 修改表
ALTER ROUTINE ALTER 或者DROP 存储过程
CREATE 创建数据库和表
CREATE ROUTINE 创建存储过程
CREATE VIEW 创建视图
DELETE 删除表数据
DROP 删除数据库和表
EXECUTE 执行存储过程
GRANT OPTION 赋权
INDEX 创建和删除索引
INSERT 添加记录
SELECT 查询记录
SHOW VIEW
UPDATE
也有权限的参考,但是不经常使用的
1.ALL 和ALL 权限是"all privileges except GRANT 选项"的缩写。
是授予所有的权限除了给其他账号授权的能力
2.USAGE 意味着 "没有权限" 相比允许连接到server.
授予这个权限会导致 在用户表里插入一条记录,但是没有任何权限。
这个会导致账户存在了, 它能用户访问server 很少的目的 比如执行SHOW VARIABLES 或者SHOW STATUS语句。
账户不能被用于访问数据库内容比如表
权限可以存在在不同的levels:
1. 任何权限都可以全局授权,一个账户处理全局权限可以使用它在任何时候。
全局权限 因此是很强大的通常只 授权于管理员账户。
比如,一个全局的DELETE 权限循序账户删除任何数据库的任何记录
2.一些权限可以用于特定的数据库 :ALTER,CRETAE,CREATE TEMPORARY TABLES,
CREATE VIEW,DELETE,DROP,GRANT OPTION,INDEX,INSERT,LOCK TABLE,SELECT,SHOW VIEW,和UPDATE
数据库-level 权限应用于所有的表和存储过程
3. 一些权限可以用于授权给指定的表:ALTER ,CREATE,DELETE,DROP ,GRANT 选项,
INDEX ,INSERT,SELECT,和UPDATE. 表-level权限应用于表的所有列
4.一些权限可以授权于指定表列:INSERT SELECT 和UPDATE
5.一些全乡可以授权给存储过程:EXECUTE,ALTER ROUTINE
34.1.2 授权表
几个授权表在mysql 数据库里包含了很多的访问控制信息。他们包含了合法的账户和持有的权限
1.user table 包含了每个账户一条信息。 记录了用户的全局权限。
它也记录了账户的其他信息,比如一些资源的限制
2. db table 列出了账户数据库的特定权限
3.tables_priv 表列出了账户特定表的权限
4.columns_priv 表流出了列的特定权限
5.proc_priv 表列出了权限 账户用于存储过程和函数
每个账户必须有一个用户表记录 因为server 使用表的内容 决定是否接受或者拒绝客户端的连接请求。
一个账号也需要记录在其他的授权表里.
mysql> grant select,insert,update,delete,create,drop,EXECUTE, EVENT, TRIGGER on test.* to test@'%' identified by '1234567';
Query OK, 0 rows affected (0.13 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.02 sec)
mysql> grant select on mysql.* to test;
Query OK, 0 rows affected (0.00 sec)
mysql> revoke select on mysql.* from test;
Query OK, 0 rows affected (0.01 sec)
此时test用户无法查询select * from mysql.user
格式:grant 权限 on 数据库名.表名 用户@登录主机 identified by "用户密码";
每个授权表有列来说明记录的账号:
1.server 决定是够客户端可以基于host,user 和password 来连接。
一个账户有一个hostname和username, 客户端可以连接,
记录在user table 里必须匹配客户端发起的主机 和username
额外的,客户端提供的密码相匹配。
2.当客户端连接后,server 决定了它的访问权限基于Host和user,db,tables_privs,column_priv和procs_priv表的user 列。
任何权限匹配user table记录可能用于全局的。
匹配的权限记录在其他的授权表应用更多的限制环境。
比如,db table记录的权限 只是应用到指定的数据库 并不是其他的数据库
使用授权表来控制 客户端的操作
还有 另外一种授权表 叫做host 由于历史原因。它不受GRANT和REVOKE 语句的影响.
因此不再这里讨论。
如果你在mysql 数据库里查找,你会看到一个user_info 表,这个表有MYSQL 管理员创建,
但是对于访问控制没有任何用户
授权表 在MySQL 安装时候以MyISAM 表被创建,
| user | CREATE TABLE `user` (
`Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
`User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '',
`Password` char(41) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '',
`Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Reload_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Shutdown_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`File_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Show_db_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Repl_slave_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Repl_client_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_user_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_tablespace_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT '',
`ssl_cipher` blob NOT NULL,
`x509_issuer` blob NOT NULL,
`x509_subject` blob NOT NULL,
`max_questions` int(11) unsigned NOT NULL DEFAULT '0',
`max_updates` int(11) unsigned NOT NULL DEFAULT '0',
`max_connections` int(11) unsigned NOT NULL DEFAULT '0',
`max_user_connections` int(11) unsigned NOT NULL DEFAULT '0',
`plugin` char(64) COLLATE utf8_bin DEFAULT '',
`authentication_string` text COLLATE utf8_bin,
`password_expired` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
PRIMARY KEY (`Host`,`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges'
MyISAM 存储引擎是强制启用的,其他的引擎不是(InnoDB 默认是启用的,但是它可以被关闭)
已经提到的,server 使用在grant tables里的信息来决定是否允许客户端连接,
来决定客户端执行的语句 是否有权限执行。
然而,server 每次不实际上访问磁盘上的grant tables 它需要校验客户端 因为
那样会导致大量的开销 。代替的是,server 把授权表读到内存里 在启动阶段
server 重新刷新 内存的授权表的拷贝 在下面的情况:
1. 你修改了 用户账户在磁盘里的表通过账户管理语句 比如CREATE USER,GRANT,REVOKE,或者SET PASSWORD
2. 你告诉server 重新加载权限表 通过flush privileges 语句
或者通过执行mysqladmin flush-privileges 或者mysqladmin reload 命令
34.1.3 应用程序用于账户管理
也可以直接修改授权表 来管理MYSQL 账户 比如(INSERT,DELETE和UPDATE)
这个过程在65.5.1章节描述,举个例子如何修改和删除可以以这样的使用。
通常,然而,推荐的方式是设置和修改MYSQL 账户 使用语句,语句提供了下面的优势:
1.使用账户管理语句 相比直接修改授权表更加简单。
它们的语法是更加自然的和更少的麻烦用于权限操作,
当你使用语句比如CREATE USER 和GRANT ,server 决定需要的修改来授权表和做出修改
2.当你执行一个账户管理语句, server 自动加载内存里的表 如果你直接修改表
用INSERT 或者DELETE语句,你需要显示的告诉server 来加载授权表 通过使用FLUSH 权限语句
34.1.4 创建和删除用户账户
3个语句create,remove,rename user账号:
1.创建用户 创建一个用户账户和任意指定一个密码。这个语句在user表里创建一条记录。
它不授予任何权限,再使用GRANT 语句(替代的,你可以使用GRANT 来创建账户同时进行授权)
下面的语句创建一个账户jim@localhost 指定账户密码是Abc123
那就是说,一个jim的用户 可以在本机连接,但是必须指定密码Abc123
CREATE USER 'jim'@'localhost' IDENTIFIED BY 'Abc123';
如果创建的用户没有包含IDENTIFIED BY 子句,账户被创建没有密码 这是不安全的也不推荐的
2. DROP USER 回收虽有的权限对于一个存在的账户 然后删除账户。
它删除所有的账户的记录 从授权表里,回收权限本身不删除账户,使用REVOKE 语句
下面的语句 删除jim@localhost 账户:
DROP USER 'jim'@'localhost';
3.RENAME USER 改变了账户的名字,可以改变长湖的名字或者hostname部分
RENAME USER 'jim'@'localhost' TO 'john'@'localhost';
对于上面3个语句,账户 是以'user_name'@'host_name'格式
34.1.5 特定的账户名称
一个账户名有username 和客户端的名字组成 账户名字使用
'user_name@host_name'格式。用户和host部分必须用单引号。
引号实际上是当值包含特定的字符 比如破折号
如果值是一个合法的 那么引号是可选的
制定一个匿名的账户(也就是说,这个账户匹配任何的username)
指定一个空字符窜对于用户部分
CREATE USER ''@'localhost';
通常情况下,最好避免不要创建匿名账号,尤其是没有密码的
主机部分对于一个账号有下面几种格式:
1.name localhost
2.一个主机名 比如mysql.example.com
3.一个IP地址 比如192.168.1.47
4.一个模式包含'%' 或者'-' 通配符。统配符是可用的设置账号允许整个domain或者整个子网访问
主机名用%.example.com 匹配任何host 在example.com域名里。
一个主机名值为192.168.% 来匹配任何主机在192.168网段里。一个host值是%匹配
任何主机,循序客户端连接到server
5.一个IP number/netmask 的组合。 值允许客户端从任何匹配的地址连接
比如,一个值10.0.0.0/255.255.255.0 匹配host 10.0.0 前面的24个位
这个格式是有用的当允许账户从一个子网来连接。
也循序省略主机部分 从账户名称
坚持适当的观点 当指定主机部分,当你连接到server时,你指定了你要连接的主机
另一方面,当server 检查了host值在授权表的host列
它使用的客户端的host 当创建一个账户时,你需要指定客户端的host
比如: 如果server 运行在server.example.com 你需要让jim 从client.example.com连接
你需要创建下面的用户:
CREATE USER 'jim'@'client.example.com';
需要注意的是 有可能有多个账户 应用去客户端
比如,如果你要创建一个jim@localhost and jim@%,
server 会使用任意一个当从本地连接的时候
34.1.6 授权
GRANT 语句的语法包括多个章节:
1. 授权
2.需要应用什么权限
3.账户需要的权限
4.密码
一个例子,下面的语句授予SELECT 权限for 所有的表在world 数据库里 给一个用户叫jim,
jim通过本地主机访问 使用密码
GRANT SELECT ON world.* TO 'jim'@'localhost' IDENTIFIED BY 'Abc123';
如果 账户不存在,GRANT 会创建它在授予指定的权限。
如果账户存在,GRANT 会修改权限
语句有下面的影响
1.语句以GRANT 关键字开头,一个或者多个权限表明需要授予的权限。
权限名字是不区分大小的。 列出多个权限,用逗号分开。
比如,需要授予jim可以操作world数据库里的记录,不只是检索他们,GRANT 语句如下:
GRANT SELECT,INSERT,DELETE,UPDATE ON world.* to 'JIM'@'localhost identified by 'Abc123';
2. ON 子句 制定授权的level(应用的范围). 你可以全局的授权 或者指定的数据库,表或者存储过程。
ON *.* 全部数据库 全部对象
ON db_name.* 该数据库下的所有对象
on db_name.table_name 指定数据库的指定表
on db_name.routine_name 指定数据库的存储过程
对于db_name 开头的格式. 它是允许省略数据库名字的资格 只是指定 *,
table_name或者过程名字。
在那种情况下,权限是授予当前数据库的所有 或者 指定的表或者过程在当前数据库里。
当给一个表或者存储过程授权的时候,有一个模糊的 如果有多个对象(表,过程或者函数)有相同的名字
为了区别对象的类型,使用关键字 TABLE,PROCEDURE或者FUNCTION 前缀:
ON TABLE db_name.table_name
ON PROCEDURE db_name.routine_name
ON FUNCTION db_name.routine_name
grant 权限在列级别指定, 使用ON子句在一个特定的表, 指定一个逗号分隔的列表在一个圆括号内
下面的语句指明可以查询 City表的3列 可以修改2列
GRANT SELECT (ID,Name,CountryCode),UPDATE(Name,CountryCode) on world.City TO 'jim'@'localhost' IDENTIFIED BY 'Abc123';
1. TO 子句指定需要授权的账户。一个账户名字 有username和客户端主机的名字组成
账户名字 是以'user_name'@'host_name' 格式。
更多的细节在34.1.5章节,“指定账户名字"
注意 user和host 部份的只必须单引号引起。
引号实际上只是当值有特定的字符 才使用
2.IDENTIFED BY 子句是可选的。 目前,它给账户设置密码。 如果账户已经存在 然后IDENTIFIED BY 指定了,
那么密码会被替换。 不过账户存在 但是IDENTIFED BY 子句是省略的,账户密码不会改变。
如果账户没有密码
作为一个安全措施,你可以阻止GTANT语句 除非指定了IDENTIFIED BY 子句
如果你需要给一个账户 给其他用户授权的功能,加上WITH GRANT OPTION 子句 举个例子,
如果你要jim有读访问world数据库的权限
使用
GRANT SELECT ON world.* TO 'jim'@'localhost' IDENTIFIED BY 'Abc123' WITH GRANT OPTION;
找出 账户有的权限,使用SHOW GRANTS 语句 它显示了GRANT语句
查看你自己的权限,使用SHOW GRANTS 不需要指定账户名字
[root@master ~]# mysql -utest -p123456
mysql> show grants;
+----------------------------------------------------------------------------------------------------------------------------------------+
| Grants for test@localhost |
+----------------------------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'test'@'localhost' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' WITH GRANT OPTION |
+----------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
查看特定用户的权限,指定账户的名字。你不能查询其他账户的权限 除非你有SELECT mysql数据库的权限
mysql> show grants for 'jim'@'localhost';
+------------------------------------------------------------------------------------------------------------+
| Grants for jim@localhost |
+------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'jim'@'localhost' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' |
| GRANT SELECT ON `test`.* TO 'jim'@'localhost' |
+------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
输出显示了SHOW GRANTS 有3部分授权组成。 ON子句表明jen有权限在全局和数据库 和表级别,
如果账号有密码,SHOW GRANTS 显示一个IDENTIFIED BY PASSWORD 子句,在GRANT 语句的最后 列出了全局选项
(PASSWORD after IDENTIFIED BY 表明密码是加密的存储在user table里不是实际值)
34.1.7 Revoking 权限
使用REVOKE 语句来回收账户的权限 他的语法包括下面的章节:
使用REVOKE 语句来回收账户的权限, 它的语法有下面的章节:
1.关键字 REVOKE 后面跟着要回收的权限
2. 一个ON子句表明 需要回收的LEVEL
3. FROM 子句指定回收权限的账户名
假设 jim 在local host 有SELECT,DELETE,INSERT和UPDATE 权限在world数据库上,
但是你要改变账户只有SELECT 访问的权限:
REVOKE DELETE,INSERT,UPDATE ON world.* FROM 'jim'@'localhost';
回收GRANT 选项权限从一个账户,你必须revoke 在一个单独的语句。
比如,如果jill有权限把它的权限赋给其他用户,你可以rvoke 如下:
REVOKE GRANT OPTION ON world.* FROM 'jill'@'localhost';
回收用户在任何level的所有的权限,revoke 有特定的语法(这个REVOKE格式没有ON子句)
REVOKE ALL PRIVILEGES,GRANT OPTION FROM 'james'@'localhost';
决定需要什么样的revoke 语句,通过SHOW GRANTS
mysql> show grants for test@'%';
+-------------------------------------------------------------------------------------------------------+
| Grants for test@% |
+-------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'test'@'%' IDENTIFIED BY PASSWORD '*6A7A490FB9DC8C33C2B025A91737077A7E9CC5E5' |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, EXECUTE, EVENT, TRIGGER ON `test`.* TO 'test'@'%' |
| GRANT SELECT ON `mysql`.* TO 'test'@'%' |
+-------------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)
file 权限才可以:
拥有file权限才可以执行 select ..into outfile和load data infile…操作,
这个输出表明账户有全局和,数据库级别的和表级别的权限。
删除其中的一些权限,转换GRANT语句到响应的REVOKE 语句。
权限的名字,权限的levels,和账户名称必须是和SHOW GRANTS 相同的。
比如,revoke 全局的文件权限 和表级别的权限 执行下面的语句:
mysql> REVOKE FILE ON *.* FROM 'jen'@'myhost.example.com';
mysql>REVOKE UPDATE ON test.mytable FROM 'jen'@myhost.example.com';
当执行REVOKE 语句,SHOW GRANTS 产生下面的结果:
如果你使用REVOKE来删除db,table_privs,colums_priv或者procs_priv 表里的所有权限,
REVOKE 删除整个记录。然而,REVOKE 不删除账户表的记录,尽管你删除了账户的所有权限。
这就是说尽管账户不再有任何权限,但是它仍然存在 因此可以用于连接到server.
如果你需要从授权表里清除所有的痕迹。你需要使用DROP USER 执行后 账户不再存在也不能用于连接到server
34.1.8 改变账户的密码
和之前讨论的,你可以指定有CREATE USER 或者GRANT 语句在IDENTIFIED BY 字句常见的账户的密码
对于CREATE USER,字句分配了初始的账户密码。
对于GRANT,字句分配初始密码或者改变当前用户的密码
改变一个存在的账户的密码不改变任何它的权限,你有两个选项:
1.使用SET PASSWORD 语句,指定账户的名字和新的密码
比如,设置jim 在local host 的密码为NewPass 使用下面的语句:
SET PASSWORD FOR 'jim'@'localhost' = PASSWORD('NewPass');
任何一个非匿名的客户端可以改变他自己的密码通过省略 FOR 字句:
SET PASSWORD = PASSWORD('NewPass');
2.
- USAGE 只连接,不授予权限
GRANT SELECT ON world.* TO 'jim'@'localhost' IDENTIFIED BY 'Abc123';
GRANT USAGE ON test.* TO 'czcb'@'localhost' IDENTIFIED BY 'Abc123';
USAGE 意味着没有权限,因此语句改变了密码没有赋任何的权限
注意 用SET PASSWORD,你可以用PASSWORD() 来加密密码, 在使用CREATE USER 和GRANT的时候没有加密
允许一个用户连接不使用特定的密码,改变password 为空字符串。然而,你不能用revoke 密码。代替的是,
使用下面的语句:
SET PASSWORD FOR 'jim'@'localhost'='';
GRANT USAGE ON *.* TO 'jim'@'localhost' IDENTIFIED BY '';
34.1.9 权限变动什么时候生效
当你用账户管理语句改变授期权表的时候,改变的影响食杂当退出客户端连接的时候:
1.表和列的权限生效时当改变的操作执行完后
2.数据库权限改变应用在下一次USE语句
3.全局和密码不应用于已经连接的客户端。
34.1.10 指定资源限制
默认的,这里没有客户端连接次数的限制和查询次数的限制, 如果那是不可用的,GRANT 可以限制账户的资源消耗:
1.每小时 账户允许连接的次数
2.每小时账户允许查询的次数
3.每小时账户允许update的次数
4.账户可以同时连接的次数
每个资源限制是指定用一个WITH 字句。 下面的例子是创建了一个账户可以使用TEST数据库,
但是可以连接到服务器只能一小时10次,每小时执行50个查询
GRANT ALL ON test.* TO 'quinn'@'localhost' IDENTIFIED BY 'SomePass'
WITH MAX_CONNECTIONS_PER_HOUR 10
MAX_QUERIES_PER_HOUR 50
MAX_updates_per_hour 20;
34.1.11 账户管理需要的权限
用于账户管理需要下面的权限:
1. 创建用户需要创建用户的权限或者有mysql数据库的INSERT 权限
2.删除用户需要CREATE USE 权限或者删除mysql 数据库的权限
3.GRANT 需要GRANT OPTION 权限,你需要有你想授权的那些权限
4.REVOKE 不是ALL PRIVILEGES 需要GRANT OPTION 权限,你也需要有你回收权限的权限
REVOKE ALL 权限需要CREATE USER 权限和UPDATE mysql 数据库的权限
34.2 客户端访问控制
这个章节描述 mysql server如何使用授权表信息来控制客户端的连接
有两个阶段来控制客户端访问:
1.第一阶段,一个客户端尝试连接,server端或者接受或者拒绝连接。
为了让尝试成功,user 表里的一些条目必须匹配 客户端连接的host ,username,和密码。
2.第2阶段(只有当客户端已经成功连接到server) server 检查收到的每个查询 看是否有权限执行
server 匹配客户端的通过授权表的条目基于客户端的主机和客户端提供的用户,然而,可能会匹配多行:
1.host值在授权表里肯那个指定的模式包含统配赋。
如果一个授权表包含了条目 myhost.example.com,
%.example.com,
%.com 和 % 它们都匹配myhost.example.com
2. user 值是不允许模式匹配的,但是一个usernameke可以使空字符串来指定一个匿名的user
当Host和User 值在user table里有多条,server 必须决定使用哪条。
server 通过排序用最指定的Host和User 列的值, 选择匹配的记录 。排序发生在下面:
1.在Host列,字符值 比如localhost,127.0.0.1,和myhost.example.com
%.example.com 排序后在最前面
比如 顺序是 %.example.com %.com %
2.在user列,非空白的用户名排序在空白username前。 也就是说非匿名的用户排序在匿名用户前
server 执行排序,它读取授权 表到内存,排序他们, 用内存的复制来做访问控制。
假设 用户表包含你下面Host和用户列的值:
34.2.1 连接请求检查:
当一个客户端尝试连接,server 匹配存储的记录 首先匹配Host值 然后匹配User值:
1. 如果jon从本地主机连接,用localhost连接Host和User列
2.如果james 从localhost连接,有两条记录用localhost 在host列 满足host
空的user值满足任何一个username
因此,第一条记录匹配client 的hostname和username.(%的条目在Host列也匹配localhost,但是server
不认为这样 ,在这种情况下 因为它已经找到了匹配的记录)
2.另一方面,如果james 从pluto.example.com 连接, 第一个条目匹配的hostname 是 %.example.com.条目的username不匹配,
因此server 继续查找。同样的事情发生在host值为%.com hostname匹配了但是username不匹配。