这片博客会注意介绍有关MySQL的以下几点说明:
- MySQL的用户管理。
- MySQL的proxy代理模式。(类似于oracle中的role)
- MySQL的日志之-二进制日志,慢查询日志,通用查询日志。
MySQL的版本为:
mysql> select version(); +------------+ | version() | +------------+ | 5.6.28-log | +------------+ 1 row in set (0.00 sec) mysql>
用户管理
MySQL用户主要包括普通用户和root用户。这两种用户的权限是不一样的。root用户是超级管理员,拥有所有权限。而普通用户只拥有创建该用户时赋予它的权限。
权限表介绍:
安装MySQL时会安装一个名为mysql的数据库。mysql数据库存储的就是权限表。用户登录之后,MySQL数据库系统会根据这些权限表的内容为每个用户赋予相应的权限。
权限表常用到的有以下几个:
- user表
- db表
- host表(mysql5.6中没有这个表)
- tables_priv表
- columns_priv表。
user表
user表是MySQL中最重要的一个权限表。user表中的所有的字段如下:
mysql> desc user; +------------------------+-----------------------------------+------+-----+-----------------------+-------+ | Field | Type | Null | Key | Default | Extra | +------------------------+-----------------------------------+------+-----+-----------------------+-------+ | Host | char(60) | NO | PRI | | | | User | char(16) | NO | PRI | | | | Password | char(41) | NO | | | | | Select_priv | enum('N','Y') | NO | | N | | | Insert_priv | enum('N','Y') | NO | | N | | | Update_priv | enum('N','Y') | NO | | N | | | Delete_priv | enum('N','Y') | NO | | N | | | Create_priv | enum('N','Y') | NO | | N | | | Drop_priv | enum('N','Y') | NO | | N | | | Reload_priv | enum('N','Y') | NO | | N | | | Shutdown_priv | enum('N','Y') | NO | | N | | | Process_priv | enum('N','Y') | NO | | N | | | File_priv | enum('N','Y') | NO | | N | | | Grant_priv | enum('N','Y') | NO | | N | | | References_priv | enum('N','Y') | NO | | N | | | Index_priv | enum('N','Y') | NO | | N | | | Alter_priv | enum('N','Y') | NO | | N | | | Show_db_priv | enum('N','Y') | NO | | N | | | Super_priv | enum('N','Y') | NO | | N | | | Create_tmp_table_priv | enum('N','Y') | NO | | N | | | Lock_tables_priv | enum('N','Y') | NO | | N | | | Execute_priv | enum('N','Y') | NO | | N | | | Repl_slave_priv | enum('N','Y') | NO | | N | | | Repl_client_priv | enum('N','Y') | NO | | N | | | Create_view_priv | enum('N','Y') | NO | | N | | | Show_view_priv | enum('N','Y') | NO | | N | | | Create_routine_priv | enum('N','Y') | NO | | N | | | Alter_routine_priv | enum('N','Y') | NO | | N | | | Create_user_priv | enum('N','Y') | NO | | N | | | Event_priv | enum('N','Y') | NO | | N | | | Trigger_priv | enum('N','Y') | NO | | N | | | Create_tablespace_priv | enum('N','Y') | NO | | N | | | ssl_type | enum('','ANY','X509','SPECIFIED') | NO | | | | | ssl_cipher | blob | NO | | NULL | | | x509_issuer | blob | NO | | NULL | | | x509_subject | blob | NO | | NULL | | | max_questions | int(11) unsigned | NO | | 0 | | | max_updates | int(11) unsigned | NO | | 0 | | | max_connections | int(11) unsigned | NO | | 0 | | | max_user_connections | int(11) unsigned | NO | | 0 | | | plugin | char(64) | YES | | mysql_native_password | | | authentication_string | text | YES | | NULL | | | password_expired | enum('N','Y') | NO | | N | | +------------------------+-----------------------------------+------+-----+-----------------------+-------+ 43 rows in set (0.01 sec) mysql>
这些字段大致可以分为四类:用户列,权限列,安全列和资源控制列。
1:用户列
user表的用户列包括Host, User, Password(注意这个password字段在MySQL5.7中更改为authentication_string)。用户登录时,首先判断的就是这3个字段。如果这3个字段同时匹配,MySQL数据库系统才会运行登录。而且,创建新用户时,也是设置这个3个字段的值。修改密码时,实际上就是修改这个password字段。
2:权限列
user表中以_priv结尾的字段,表示某些权限。这些字段的值只Y和N。从安全角度考虑,这些字段的默认值都是“N”。可以使用grant语句为用户赋予一些权限,也可以通过update语句更新user表的方式来设置权限。
Grant_priv: 表示是否拥有grant权限。
Shutdown_priv:表示是否拥有停止MySQL服务的权限。
Super_priv:表示是否拥有超级权限。
Execute_priv:表示是否拥有执行存储过程和函数的权限。
3:安全列
user表的安全列只有4个字段,分别是ssl_type,ssl_cipher,x509_issuer,x509_subject,其中ssl用于加密;x509标准可以用来标识用户。通常标准不支持ssl,可以使用如下命令查看是否支持。
mysql> show variables like "have_openssl"; +---------------+----------+ | Variable_name | Value | +---------------+----------+ | have_openssl | DISABLED | +---------------+----------+ 1 row in set (0.00 sec) 如上,则没有支持ssl加密功能
具体这个加密字段怎么使用,再研究一下吧!
4:资源控制列
user表的4个资源控制列是:
max_questions:每个小时可以允许执行多少次查询。
max_updates:每个小时可以允许执行多少次更新。
max_connections:规定每个小时可以建立多少练级。
max_user_connections:规定单个用户可以同时具有的连接数。
这些字段的默认值为0,表示没有限制。
db表
host表在mysql5.6中已经没有了,这里会简单提下。
db表的用户列有3个字段,分别是Host, db和user。host表的用户列有两个字段,分别是host和db。host表是db表的扩展。如果db表中找不到host字段,就需要到host表中寻找。
user表中的权限是针对所有的数据库的。db表中的权限是针对某个数据库的。
两个用户user1和user,分别赋予如下权限:
mysql> grant all privileges on *.* to "user1"@"%" identified by "123456"; #对所有的数据库 Query OK, 0 rows affected (0.00 sec) mysql> grant all privileges on test.* to "user2"@"%" identified by "123456"; #对test库 Query OK, 0 rows affected (0.00 sec) #mysql中的用户就是“username”@“host”的形式,合在一起称作用户
mysql> select * from user where user in ("user1", "user2")\G *************************** 1. row *************************** Host: % User: user1 Password: *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 Select_priv: Y Insert_priv: Y Update_priv: Y Delete_priv: Y Create_priv: Y Drop_priv: Y Reload_priv: Y Shutdown_priv: Y Process_priv: Y File_priv: Y Grant_priv: N References_priv: Y Index_priv: Y Alter_priv: Y Show_db_priv: Y Super_priv: Y Create_tmp_table_priv: Y Lock_tables_priv: Y Execute_priv: Y Repl_slave_priv: Y Repl_client_priv: Y Create_view_priv: Y Show_view_priv: Y Create_routine_priv: Y Alter_routine_priv: Y Create_user_priv: Y Event_priv: Y Trigger_priv: Y Create_tablespace_priv: Y ssl_type: ssl_cipher: x509_issuer: x509_subject: max_questions: 0 max_updates: 0 max_connections: 0 max_user_connections: 0 plugin: mysql_native_password authentication_string: password_expired: N *************************** 2. row *************************** Host: % User: user2 Password: *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 Select_priv: N Insert_priv: N Update_priv: N Delete_priv: N Create_priv: N Drop_priv: N Reload_priv: N Shutdown_priv: N Process_priv: N File_priv: N Grant_priv: N References_priv: N Index_priv: N Alter_priv: N Show_db_priv: N Super_priv: N Create_tmp_table_priv: N Lock_tables_priv: N Execute_priv: N Repl_slave_priv: N Repl_client_priv: N Create_view_priv: N Show_view_priv: N Create_routine_priv: N Alter_routine_priv: N Create_user_priv: N Event_priv: N Trigger_priv: N Create_tablespace_priv: N ssl_type: ssl_cipher: x509_issuer: x509_subject: max_questions: 0 max_updates: 0 max_connections: 0 max_user_connections: 0 plugin: mysql_native_password authentication_string: password_expired: N 2 rows in set (0.00 sec) mysql> #user1用户的权限列为y,user2用户的权限列为N。
查看db表:
mysql> select * from db where user in ("user1", "user2")\G *************************** 1. row *************************** Host: % Db: test User: user2 Select_priv: Y Insert_priv: Y Update_priv: Y Delete_priv: Y Create_priv: Y Drop_priv: Y 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.02 sec) #只有用户user2有记录,用户user1没有记录
如果某个用户对所有的数据库中的表,都有某个操作,那么对应的user中的这个权限为“Y”;如果这个用户只是对某一个数据库有操作,那么对用的user表这个操作权限字段值为“N”,则在db表中对应的权限字段值为“Y”。
tables_priv表和columns_priv表
tables_priv:对单个表进行的权限设置。columns_priv对单个表的列进行权限设置。表的基本结构如下:
mysql> desc tables_priv\G *************************** 1. row *************************** Field: Host Type: char(60) Null: NO Key: PRI Default: Extra: *************************** 2. row *************************** Field: Db Type: char(64) Null: NO Key: PRI Default: Extra: *************************** 3. row *************************** Field: User Type: char(16) Null: NO Key: PRI Default: Extra: *************************** 4. row *************************** Field: Table_name Type: char(64) Null: NO Key: PRI Default: Extra: *************************** 5. row *************************** Field: Grantor Type: char(77) Null: NO Key: MUL Default: Extra: *************************** 6. row *************************** Field: Timestamp Type: timestamp Null: NO Key: Default: CURRENT_TIMESTAMP Extra: on update CURRENT_TIMESTAMP *************************** 7. row *************************** Field: Table_priv Type: set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') Null: NO Key: Default: Extra: *************************** 8. row *************************** Field: Column_priv Type: set('Select','Insert','Update','References') Null: NO Key: Default: Extra: 8 rows in set (0.00 sec) mysql>
mysql> desc columns_priv; +-------------+----------------------------------------------+------+-----+-------------------+-----------------------------+ | Field | Type | Null | Key | Default | Extra | +-------------+----------------------------------------------+------+-----+-------------------+-----------------------------+ | Host | char(60) | NO | PRI | | | | Db | char(64) | NO | PRI | | | | User | char(16) | NO | PRI | | | | Table_name | char(64) | NO | PRI | | | | Column_name | char(64) | NO | PRI | | | | Timestamp | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP | | Column_priv | set('Select','Insert','Update','References') | NO | | | | +-------------+----------------------------------------------+------+-----+-------------------+-----------------------------+ 7 rows in set (0.00 sec) mysql>
tables_priv:包含8个字段。前4个字段分别表示主机名,数据库名,用户名和表名。
Table_priv表示对表进行的操作权限,在表结构中已经指明有哪些权限。
Column_priv:表示对表中的列进行的操作权限。
Timestamp:表示修改权限的时间。
Grantor:表示权限是谁设置的。
columns_priv:表包含7个字段,Column_name字段表示可以对哪些数据列进行操作。
MySQL中的权限分配是按照user表,db表,tables_priv表和columns_priv表的顺序进行分配的。数据库系统中,先判断user表中的值是否为“Y”,就不需要检查后面的表。如果user表值为“N”,则依次检查db表,tables_priv表和columns_priv。
procs_priv表
procs_priv表可以对存储过程和存储函数进行权限设置。其表的基本结构如下:
mysql> desc procs_priv; +--------------+----------------------------------------+------+-----+-------------------+-----------------------------+ | Field | Type | Null | Key | Default | Extra | +--------------+----------------------------------------+------+-----+-------------------+-----------------------------+ | Host | char(60) | NO | PRI | | | | Db | char(64) | NO | PRI | | | | User | char(16) | NO | PRI | | | | Routine_name | char(64) | NO | PRI | | | | Routine_type | enum('FUNCTION','PROCEDURE') | NO | PRI | NULL | | | Grantor | char(77) | NO | MUL | | | | Proc_priv | set('Execute','Alter Routine','Grant') | NO | | | | | Timestamp | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP | +--------------+----------------------------------------+------+-----+-------------------+-----------------------------+ 8 rows in set (0.00 sec) mysql>
Host, Db,User:分别表示主机名,数据库名和用户名。
Routine_name: 表示存储过程或者函数的名字。
Routine_type:有两个取值'FUNCTION','PROCEDURE',分别表示函数和存储过程。
Proc_priv:表示拥有的权限。
Grantor:字段存储全是是谁设置的。
Timestamp:表示更新的时间。
用户管理
对mysql用户的管理,本质上就是对上面的几张表的增删改查。
创建用户:
mysql> create user "test1"@"localhost" identified by "123456"; Query OK, 0 rows affected (0.00 sec)
对用户授权:
mysql> grant select on test.* to "test1"@"localhost"; Query OK, 0 rows affected (0.00 sec) mysql>
MySQL中用户包含两部分用户名和主机名,在使用的时候需要使用形如“username”@"host"的形式。
查看某用户的权限:
mysql> show grants for "test1"@"localhost"; +--------------------------------------------------------------------------------------------------------------+ | Grants for test1@localhost | +--------------------------------------------------------------------------------------------------------------+ | GRANT USAGE ON *.* TO 'test1'@'localhost' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' | | GRANT SELECT ON `test`.* TO 'test1'@'localhost' | +--------------------------------------------------------------------------------------------------------------+ 2 rows in set (0.00 sec)
设置权限之后,需要刷新权限表,所做的更改会立即生效:
mysql> flush privileges; Query OK, 0 rows affected (0.00 sec) mysql>
收回权限:
mysql> revoke select on `test`.* from 'test1'@'localhost'; Query OK, 0 rows affected (0.01 sec) mysql> help revoke; # 在MySQLshell中查看帮助信息 Name: 'REVOKE' Description: Syntax: REVOKE priv_type [(column_list)] [, priv_type [(column_list)]] ... ON [object_type] priv_level FROM user [, user] ... REVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ... REVOKE PROXY ON user FROM user [, user] ... .......
删除用户:
mysql> drop user "test1"@"localhost"; Query OK, 0 rows affected (0.00 sec)
使用grant语句来创建用户并且授权,grant语句可以使用一条命令完成创建用户和授权两个步骤,但是在MySQL5.7版本中,是会报警告说,不提倡使用。
mysql> mysql> grant all privileges on *.* to "test2"@"localhost" identified by "123456"; Query OK, 0 rows affected, 1 warning (0.01 sec) mysql> show warnings; +---------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Level | Code | Message | +---------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Warning | 1287 | Using GRANT statement to modify existing user's properties other than privileges is deprecated and will be removed in future release. Use ALTER USER statement for this operation. | +---------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> show grants for "test2"@"localhost"; +----------------------------------------------------+ | Grants for test2@localhost | +----------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'test2'@'localhost' | +----------------------------------------------------+ 1 row in set (0.00 sec) mysql>
MySQL中的proxy
我们需要读一批的用户进行操作,这些用户拥有相同的权限。这时候如果我们引入角色这个概念会方便的多,先创建一个角色,然后把这一批用户和这个角色相关联,然后这一批用户就拥有了这个角色的权限。
但是MySQL中并没有角色这个概念,我们可以使用proxy来模拟角色的使用。
这个proxy在MySQL5.6中并不支持,虽然MySQL5.6中有这个表,但是不支持,需要使用MySQL5.7!
mysql> create user 'user1'@"localhost"; Query OK, 0 rows affected (0.02 sec) mysql> grant select , update on test.* to 'user1'@"localhost"; Query OK, 0 rows affected (0.02 sec) #再创建两个用户,使其与user1有相同的权利。 mysql> create user 'user2'@"localhost"; Query OK, 0 rows affected (0.00 sec) mysql> create user 'user3'@"localhost"; Query OK, 0 rows affected (0.01 sec) #先创建两个用户 #设置代理 mysql> grant proxy on 'user1'@"localhost" to 'user2'@"localhost"; Query OK, 0 rows affected (0.00 sec) mysql> grant proxy on 'user1'@"localhost" to 'user3'@"localhost"; Query OK, 0 rows affected (0.02 sec) #查看用户权限 mysql> show grants for 'user2'@"localhost"; +-----------------------------------------------------------+ | Grants for user2@localhost | +-----------------------------------------------------------+ | GRANT USAGE ON *.* TO 'user2'@'localhost' | | GRANT PROXY ON 'user1'@'localhost' TO 'user2'@'localhost' | +-----------------------------------------------------------+ 2 rows in set (0.00 sec) mysql>
以这样的方式设置代理之后,用户user2和user2就拥有了user1的权限。