mysql 的权限体系介绍
mysql 的权限体系大致分为5个层级:
全局层级
全局权限适用于一个给定服务器中的所有数据库。这些权限存储在mysql.user表中。GRANT ALL ON *.*和REVOKE ALL ON *.*只授予和撤销全局权限。
数据库层级
数据库权限适用于一个给定数据库中的所有目标。这些权限存储在mysql.db和mysql.host表中。GRANT ALL ON db_name.*和REVOKE ALL ON db_name.*只授予和撤销数据库权限。
表层级
表权限适用于一个给定表中的所有列。这些权限存储在mysql.talbes_priv表中。GRANT ALL ON db_name.tbl_name和REVOKE ALL ON db_name.tbl_name只授予和撤销表权限。
列层级
列权限适用于一个给定表中的单一列。这些权限存储在mysql.columns_priv表中。当使用REVOKE时,您必须指定与被授权列相同的列。
子程序层级
CREATE ROUTINE, ALTER ROUTINE, EXECUTE和GRANT权限适用于已存储的子程序。这些权限可以被授予为全局层级和数据库层级。而且,除了CREATE ROUTINE外,这些权限可以被授予为子程序层级,并存储在
mysql.procs_priv表中。
这些权限信息存储在下面的系统表中:
mysql.user
mysql.db
mysql.host
mysql.table_priv
mysql.column_priv
当用户连接进来,mysqld会通过上面的这些表对用户权限进行验证!
注意:
当后续目标是一个表、一个已存储的函数或一个已存储的过程时,object_type子句应被指定为TABLE、FUNCTION或PROCEDURE。当从旧版本的MySQL升级时,要使用本子句,您必须升级您的授权表。请我们可以用 CREATE
USER 或 GRANT 创建用户,后者还同时分配相关权限。而 REVOKE 则用于删除用户权限,DROP USER 删除账户。
MySQL 赋予用户权限命令语法为:
grant 权限 on 数据库对象 to 用户;
grant 权限 on 数据库对象 to 用户 identified by "密码";
grant 权限 on 数据库对象 to 用户@"ip" identified by "密码"
GRANT 语法:
GRANT privileges (columns) ON what TO user IDENTIFIED BY "password" WITH GRANT OPTION; (表示该用户可以为其他用户分配权限)
privileges 列表:
* ALTER: 修改表和索引。
* CREATE: 创建数据库和表。
* DELETE: 删除表中已有的记录。
* DROP: 抛弃(删除)数据库和表。
* INDEX: 创建或抛弃索引。
* INSERT: 向表中插入新行。
* REFERENCE:未使用。
* SELECT: 检索表中的记录。
* UPDATE: 修改现存表记录。
* FILE: 读或写服务器上的文件。
* PROCESS: 查看服务器中执行的线程信息或杀死线程。
* RELOAD: 重载授权表或清空日志、主机缓存或表缓存。
* SHUTDOWN: 关闭服务器。
* ALL: 所有权限,ALL PRIVILEGES同义词。
* USAGE: 特殊的 "无权限" 权限。
user 账户包括 "username" 和 "host" 两部分
即是username@host,后者表示该用户被允许从何地接入。
user@'%' 表示用户user可以从任何地址访问本地的数据库,默认可以省略。
还可以是 "user@10.250.7.%"、"user1@ %.abc.com" 等。
数据库格式为 db.table,可以是 "test.*" 或 "*.*",前者表示 test 数据库的所有表,后者表示所有数据库的所有表。
子句 "WITH GRANT OPTION" 表示该用户可以为其他用户分配权限。
使用grant 命令创建用户或者进行授权之后,需要使用flush privileges刷新MySQL的系统权限相关表,否则会出现拒绝访问,或者重新启动mysql服务器,来使新设置生效。当然后者并不是一种好想法!
比如:
一 grant普通数据用户yangql402查询、插入、更新、删除 数据库(test)中所有表数据的权利。grant select, insert, update, delete on test.* to yangql402@'%';
二 grant数据库开发人员(yangql402),创建表、索引、视图、存储过程、函数。。。等权限。
grant创建、修改、删除 MySQL 数据表结构权限。
grant create on test.* to yangql402@'10.250.7.225';
grant alter on test.* to yangql402@'10.250.7.225';
grant drop on test.* to yangql402@'10.250.7.225';
grant 操作 MySQL 外键权限,官方文档上说未使用!
grant references on test.* to yangql402@'10.250.7.225';
grant 操作 MySQL 临时表权限。
grant create temporary tables on test.* to yangql402@'10.250.7.225';
grant 操作 MySQL 索引权限。
grant index on test.* to yangql402@'10.250.7.225';
grant 操作 MySQL 视图、查看视图源代码 权限。
grant create view on test.* to yangql402@'10.250.7.225';grant show view on test.* to yangql402@'10.250.7.225';
grant 操作 MySQL 存储过程、函数 权限。
grant create routine on test.* to yangql402@'10.250.7.225';
grant alter routine on test.* to yangql402@'10.250.7.225';
grant execute on test.* to yangql402@'10.250.7.225';
三 grant 普通DBA管理某个MySQL数据库(test)的权限。grant all privileges on test to dba@'localhost'其中,关键字 “privileges” 可以省略。
四 grant 高级 DBA 管理 MySQL 中所有数据库的权限。grant all on *.* to dba@'localhost'
五 MySQL grant 权限,分别可以作用在多个层次上。
a. grant 作用在整个 MySQL 服务器上:
grant select on *.* to dba@localhost; -- dba 可以查询 MySQL 中所有数据库中的表。
grant all on *.* to dba@localhost; -- dba 可以管理 MySQL 中的所有数据库
b. grant 作用在单个数据库上:
grant select on test.* to dba@localhost; -- dba 可以查询 test 中的表。
c. grant 作用在单个数据表上:
grant select, insert, update, delete on test.yql8 to dba@localhost;
d. grant 作用在表中的列上:
grant select(id, se, rank) on test.yql8 to dba@localhost;
e. grant 作用在存储过程、函数上:
grant execute on procedure test.yql8 to 'dba'@'localhost';
grant execute on function test.yql8 to 'dba'@'localhost';
六 查看用户权限查看当前用户自己的权限:show grants;查看其他 MySQL 用户权限:show grants for dba@localhost;
七 撤销用户权限使用revoke 命令来注销用户的权限,具体语法:要撤销所有权限,需使用以下语法。此语法用于取消对于已命名的用户的所有全局层级、数据库层级、表层级和列层级的权限。REVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ...也可以指定具体的权限比如:REVOKE SELECT FROM yangql402@"10.250.7.249";注意:1 使用GRANT或REVOKE,操作者必须拥有GRANT OPTION权限,并且您必须用于您正在授予或撤销的权限。2 使用REVOKE撤销全部权限,操作者必须拥有mysql数据库的全局CREATE USER权限或UPDATE权限。
八 删除用户:DROP USER user;其中user 账户包括 "username" 和 "host" 两部分 即是username@host;如果创建的时候为 yangql@"10.250.7.225",则删除的时候必须使用drop user yangql@"10.250.7.225",否则会报错!mysql> drop user yangql402;ERROR 1396 (HY000): Operation DROP USER failed for 'yangql402'@'10.250.7.225'mysql> drop user yangql402@'10.250.7.225';Query OK, 0 rows affected (0.01 sec)
参考; MYSQL 官方文档http://dev.mysql.com/doc/refman/5.1/zh/sql-syntax.html#account-management-sql
点击这里 | 点击这里 | 点击这里 |
---|---|---|
权限 | 权限级别 | 权限说明 |
CREATE | 数据库、表或索引 | 创建数据库、表或索引权限 |
DROP | 数据库或表 | 删除数据库或表权限 |
GRANT OPTION | 数据库、表或保存的程序 | 赋予权限选项 |
REFERENCES | 数据库或表 | |
ALTER | 表 | 更改表,比如添加字段、索引等 |
DELETE | 表 | 删除数据权限 |
INDEX | 表 | 索引权限 |
INSERT | 表 | 插入权限 |
SELECT | 表 | 查询权限 |
UPDATE | 表 | 更新权限 |
CREATE VIEW | 视图 | 创建视图权限 |
SHOW VIEW | 视图 | 查看视图权限 |
ALTER ROUTINE | 存储过程 | 更改存储过程权限 |
CREATE ROUTINE | 存储过程 | 创建存储过程权限 |
EXECUTE | 存储过程 | 执行存储过程权限 |
FILE | 服务器主机上的文件访问 | 文件访问权限 |
CREATE TEMPORARY TABLES | 服务器管理 | 创建临时表权限 |
LOCK TABLES | 服务器管理 | 锁表权限 |
CREATE USER | 服务器管理 | 创建用户权限 |
PROCESS | 服务器管理 | 查看进程权限 |
RELOAD | 服务器管理 | 执行flush-hosts, flush-logs, flush-privileges, flush-status, flush-tables, flush-threads, refresh, reload等命令的权限 |
REPLICATION CLIENT | 服务器管理 | 复制权限 |
REPLICATION SLAVE | 服务器管理 | 复制权限 |
SHOW DATABASES | 服务器管理 | 查看数据库权限 |
SHUTDOWN | 服务器管理 | 关闭数据库权限 |
SUPER | 服务器管理 | 执行kill线程权限 |
MYSQL的权限如何分布,就是针对表可以设置什么权限,针对列可以设置什么权限等等,这个可以从官方文档中的一个表来说明:
点击这里 | 点击这里 |
---|---|
权限分布 | 可能的设置的权限 |
表权限 | 'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter' |
列权限 | 'Select', 'Insert', 'Update', 'References' |
过程权限 | 'Execute', 'Alter Routine', 'Grant' |
二、MySQL权限经验原则:
权限控制主要是出于安全因素,因此需要遵循一下几个经验原则:
1、只授予能满足需要的最小权限,防止用户干坏事。比如用户只是需要查询,那就只给select权限就可以了,不要给用户赋予update、insert或者delete权限。
2、创建用户的时候限制用户的登录主机,一般是限制成指定IP或者内网IP段。
3、初始化数据库的时候删除没有密码的用户。安装完数据库的时候会自动创建一些用户,这些用户默认没有密码。
4、为每个用户设置满足密码复杂度的密码。
5、定期清理不需要的用户。回收权限或者删除用户。
三、MySQL权限实战:
1、GRANT命令使用说明:
先来看一个例子,创建一个只允许从本地登录的超级用户jack,并允许将权限赋予别的用户,密码为:jack.
mysql> grant all privileges on *.* to jack@'localhost' identified by "jack" with grant option;
Query OK, 0 rows affected (0.01 sec) GRANT命令说明:
ALL PRIVILEGES 是表示所有权限,你也可以使用select、update等权限。
ON 用来指定权限针对哪些库和表。
*.* 中前面的*号用来指定数据库名,后面的*号用来指定表名。
TO 表示将权限赋予某个用户。
jack@'localhost' 表示jack用户,@后面接限制的主机,可以是IP、IP段、域名以及%,%表示任何地方。注意:这里%有的版本不包括本地,以前碰到过给某个用户设置 了%允许任何地方登录,但是在本地登录不了,这个和版本有关系,遇到这个问题再加一个localhost的用户就可以了。
IDENTIFIED BY 指定用户的登录密码。
WITH GRANT OPTION 这个选项表示该用户可以将自己拥有的权限授权给别人。注意:经常有人在创建操作用户的时候不指定WITH GRANT OPTION选项导致后来该用户不能使用GRANT命令创建用户或者给其它用户授权。
备注:可以使用GRANT重复给用户添加权限,权限叠加,比如你先给用户添加一个select权限,然后又给用户添加一个insert权限,那么该用户就同时拥有了select和insert权限。
2、刷新权限
使用这个命令使权限生效,尤其是你对那些权限表user、db、host等做了update或者delete更新的时候。以前遇到过使用grant后权限没有更新的情况,只要对权限做了更改就使用FLUSH PRIVILEGES命令来刷新权限。
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec) 3、查看权限
查看当前用户的权限:
mysql> show grants;
+---------------------------------------------------------------------+
| Grants for root@localhost |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+
2 rows in set (0.00 sec)
查看某个用户的权限:
mysql> show grants for 'jack'@'%';
+-----------------------------------------------------------------------------------------------------+
| Grants for jack@% |
+-----------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'jack'@'%' IDENTIFIED BY PASSWORD '*9BCDC990E611B8D852EFAF1E3919AB6AC8C8A9F0' |
+-----------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec) 4、回收权限
mysql> revoke delete on *.* from 'jack'@'localhost';
Query OK, 0 rows affected (0.01 sec) 5、删除用户
mysql> select host,user,password from user;
+-----------+------+-------------------------------------------+
| host | user | password |
+-----------+------+-------------------------------------------+
| localhost | root | |
| rhel5.4 | root | |
| 127.0.0.1 | root | |
| ::1 | root | |
| localhost | | |
| rhel5.4 | | |
| localhost | jack | *9BCDC990E611B8D852EFAF1E3919AB6AC8C8A9F0 |
+-----------+------+-------------------------------------------+
7 rows in set (0.00 sec)
mysql> drop user 'jack'@'localhost';
Query OK, 0 rows affected (0.01 sec) 6、对账户重命名
mysql> rename user 'jack'@'%' to 'jim'@'%';
Query OK, 0 rows affected (0.00 sec) 7、修改密码
1、用set password命令
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456');
Query OK, 0 rows affected (0.00 sec)
2、用mysqladmin
[root@rhel5 ~]# mysqladmin -uroot -p123456 password 1234abcd
备注:
格式:mysqladmin -u用户名 -p旧密码 password 新密码
3、用update直接编辑user表
mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> update user set PASSWORD = PASSWORD('1234abcd') where user = 'root';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
4、在丢失root密码的时候:
[root@rhel5 ~]# mysqld_safe --skip-grant-tables &
[1] 15953
[root@rhel5 ~]# 130911 09:35:33 mysqld_safe Logging to '/mysql/mysql5.5/data/rhel5.4.err'.
130911 09:35:33 mysqld_safe Starting mysqld daemon with databases from /mysql/mysql5.5/data
[root@rhel5 ~]# mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.22 Source distribution
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> \s
--------------
mysql Ver 14.14 Distrib 5.5.22, for Linux (i686) using EditLine wrapper
Connection id: 2
Current database:
Current user: root@
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server version: 5.5.22 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: 36 sec
Threads: 1 Questions: 5 Slow queries: 0 Opens: 23 Flush tables: 1 Open tables: 18 Queries per second avg: 0.138
--------------
mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> update user set password = PASSWORD('123456') where user = 'root';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)