1.MySQL访问权限


  MySQL权限系统最重要的功能就是,验证从指定主机连接的用户,并将该用户与数据库上的权限关联。关于用户管理的箴言:

    明确指定允许访问的用户
    不要创建可以建表、删表的用户(table、db)
    把密码跟与用户关联,不要把密码与对象关联(db、table、routine、etc……)

  服务器在mysql库保存权限信息,服务启动时把这些表的内容读入内存,验证权限时依据内中的授权表比对。MySQL认为没有道理来自不同主机访问的同一个用户属于相同的身份,对于用户身份的是同时比对主机名、与用户名。


1.1.授权表

  MySQL使用多个表管理用户权限,使用账户管理语句可以修改这些表的内容(CREATE USER、GRANT、REVOKE)。每个授权表包含“作用域”、“特权”。user表作用域列决定是否拒绝或允许连接接入。user表的权限列作用于所有database。db表作用域决定那个用户允许访问那个db。db表的权限列控制访问db时允许的操作。……



作用域
说明
user
Host、User

用户账户访问实例

全局权限、……

db
Db、Host、User数据库级别权限
tables_priv
Table_name、Db、Host、User表级别权限
columns_priv
Columns_name、Table_name、Db、Host、User……
procs_priv
Routine_name、Routine_type、Db、Host、User存储过程、函数……
proxies_priv
Proxied_host、Proxied_user、Db、Host、User代理用户权限


1.2.指定账户名称

  MySQL帐户名”由用户名和主机名组成。研究下如何编写账户名称,包括特殊值和通配符规则。

  帐户名的语法格式:'user_name'@'host_name'。使用“CREATE_USER”、“GRANT”、“SET PASSWORD”这些操作时,帐户名写成'user_name',就被实例解读为'user_name'@'%'。帐户名在指定的时候,引号不是必须的;当user_name包含特殊字符(空格、-)、host_name包含特殊字符或通配符。就像'sunny bay'@'%.51cto.com'。如果账户名称这样指定'user@host',实例会认为其为'user@host'@'host_name'。

  创建账户时,user_name和host_name分别存在了系统库user表的不同字段里。user_name区分大小写,host_name区分大小写。当user_name指定成''@'host_name',认为就是个匿名用户。

  host_name可以包含通配符。可以是域名、主机名、ip地址、ip/prefix。

mysql> create user 'david'@'10.0.0.0/26';
Query OK, 0 rows affected (0.00 sec)

mysql> select count(*) from user where user='david';
+----------+
| count(*) |
+----------+
|        1 |
+----------+
1 row in set (0.02 sec)


1.3.访问控制

  一个用户连接到MySQL服务时,服务例程会检查用户账户名和密码。在user表可以找到对应条目时,就允许建立连接,否则就拒绝。(检查作用域)

  允许创建连接会话后,进入访问控制第二阶段。对于该连接会话上发出的请求,确定要完成的操作,然后检查权限是否允许。(检查特权列)


1.4.权限变更生效

  数据库实例验证连接时,依据内存中的授权表信息。当使用GRANT、REVOKE、SET PASSWORD、RENAME USER这些语句修改了mysql库中的授权表时,实例会检测到这些变化,并立即重新加载到内存授权表。

  倘若修改mysql库中的授权表时,使用的是INSERT、UPDATE、DELETE时,就需要自己手动重新加载授权表。

# 刷新内存授权表
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

C:\Users\Administrator>mysqladmin -uroot -p flush-privileges
Enter password: ******

C:\Users\Administrator>mysqladmin -uroot -p reload
Enter password: ******

  加载内存授权表后,对于已经建立连接会话的用户需要退出重新建立会话。数据库级别权限修改会在下一次执行use db_name时生效。表、列级别权限,会在下一次请求时生效。应用程序客户端,使用本地缓存的情况下刷新有可能无效。

  当服务启动时,使用了选项--skip-grant-tables,授权表不被加载,而且不会验证用户权限(stage1 & stage2)。为了让实例验证用户权限,加载授权表即可。


1.5.FAQ

◎服务没有运行

  报错信息

C:\Users\Administrator>mysql
ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)

[view@file ~]$ mysql
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

◎没有监听网络协议

  启动服务时,使用了--skip-networking、--bind-address=127.0.0.1。

◎选项错误

  客户端程序使用了错误的配置文件(环境变量)作为命令选项。可以使用选项--no-defaults,跳过默认选项。

Default options are read from the following files in the given order:
C:\Windows\my.ini C:\Windows\my.cnf C:\my.ini C:\my.cnf C:\Program Files\MySQL\MySQL Server 5.5\my.ini C:\Program Files\MySQL\MySQL Server 5.5\my.cnf
The following groups are read: mysql client
The following options may be given as the first argument:
--print-defaults        Print the program argument list and exit.
--no-defaults           Don't read default options from any option file.
--defaults-file=#       Only read default options from the given file #.
--defaults-extra-file=# Read this file after the global files are read.
C:\Users\Administrator>mysql --print-defaults
mysql would have been started with the following arguments:
--port=3306 --default-character-set=utf8


2.用户账户管理


2.1.创建用户

  用户信息保存在 mysql 库的 user 表(授权表)。创建用户的方法:①使用账户管理语句 CREATE USER 和 GRANT。②直接操作授权表,如、INSERT、UPDATE 和 DELETE。

  增加用户,以 root 权限操作(用户不能建表、不能删除表

# 创建用户
mysql> create user 'username'@'clienthost' identified by 'userpassword';
Query OK, 0 rows affected (0.00 sec)

# 授权
mysql> grant all privileges on dbname.table to 'username'@'clienthost';
Query OK, 0 rows affected (0.00 sec)

# 撤销权限
mysql> revoke create, drop on dbname.* from 'username'@'clienthost';
Query OK, 0 rows affected (0.00 sec)


  查看用户授予了什么权限

mysql> show grants for 'username'@'clienthost';
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for username@clienthost                |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'username'@'clienthost' IDENTIFIED BY PASSWORD '*36D54E64A3248C55234862F9C6E93BF10D9F09F0'                |
| GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `dbname`.* TO 'username'@'clienthost' |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> select * from mysql.db where user='username' \G
*************************** 1. row ***************************
                 Host: clienthost
                   Db: dbname
                 User: username
          Select_priv: Y
          Insert_priv: Y
          Update_priv: Y
          Delete_priv: Y
          Create_priv: N
            Drop_priv: N
           Grant_priv: N
      References_priv: Y
           Index_priv: Y
           Alter_priv: Y
Create_tmp_table_priv: Y
     Lock_tables_priv: Y
     Create_view_priv: Y
       Show_view_priv: Y
  Create_routine_priv: Y
   Alter_routine_priv: Y
         Execute_priv: Y
           Event_priv: Y
         Trigger_priv: Y
1 row in set (0.00 sec)


2.2.删除用户

  以root登录,删除刚刚创建的用户

mysql> drop user 'username'@'clienthost';