【MySQL】9:访问控制

数据库的目标是为了数据的集中管理和共享。但是数据库中的数据针对不同的人本就应该有不同的访问权限,以下就是对数据访问管理的概况。

9.1 用户管理

MySQL的用户分两类:

  1. 超级管理员用户root(在安装时已默认建立,密码为空,拥有数据库中的所有权限如数据库的备份与还原),
  2. 普通用户(由管理员创建,只拥有创建时管理员赋予的权限)

MySQL的用户信息是存放在数据库mysql的user表中的。
因此,在MySQL中,对用户的管理,既可以使用MySQL特定的语句,也可以使用标准的SQL语句,当然前提是拥有相关权限。

用户信息存放在数据库mysql中的user表中。

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sakila             |
| sys                |
| world              |
+--------------------+
10 rows in set (0.01 sec)

mysql> use mysql;
Database changed
mysql> show tables;
+---------------------------+
| Tables_in_mysql           |
+---------------------------+
| columns_priv              |
| ....               |
| user                      |
+---------------------------+
33 rows in set (0.03 sec)

mysql> desc user;
// 查看user表结构
// 这里重点关注三个字段:
// host:可以登录数据库的主机地址
// user:用户名
// authentication_string:加密过的登陆密码
// _priv 结尾的字段:表明用户的权限
基本语法:
create user 用户名@主机名
//用户名区分大小写,主机名连接来自的主机;百分符表示一组主机,localhost表示本地主机
[ identified by [password] ‘密码’]
//密码区分大小写;password省略则自动用密码函数进行加密,不省略则用加密函数后的明文作为密码
[ , 用户名@主机名[identified by [password][‘密码’]] [ ,... ]
//可以同时创建多个数据库用户,中间用逗号分隔。

实践:

mysql> create user cat@localhost identified by 'cat123';
Query OK, 0 rows affected (0.02 sec)

mysql> select host,user,authentication_string from user;
+-----------+------------------+------------------------------------------------------------------------+
| host      | user             | authentication_string                                                  |
+-----------+------------------+------------------------------------------------------------------------+
| localhost | cat              | $A$005$I3X*!v/Uf2+Ef^pBk08rUDb.7YBIitg3KJ622TocHgkbzQCHzfLTLy117 |
+-----------+------------------+------------------------------------------------------------------------+

mysql> exit

GRANT语句给用户分配权限

基本语法:
grant 权限类别//权限类别表示各类权限,用逗号隔开;
on 数据库名.表名
to 用户名@主机名
[,用户名@主机名] [,...]

实践证明貌似Grant语句在8.0.18版本里不能添加用户,只能附加权限。

修改用户名
rename user 旧用户名@主机名 to 新用户名@主机名;

mysql> rename user cat@localhost to mouse@localhost;
Query OK, 0 rows affected (0.02 sec)
//要为现有帐户分配或更改密码,请将该 ALTER USER语句与以下IDENTIFIED BY子句一起使用 :
ALTER USER 'jeffrey'@'localhost' IDENTIFIED BY 'password';

//如果您不是以匿名用户身份连接的,则可以更改自己的密码,而无需直接命名自己的帐户:
ALTER USER USER() IDENTIFIED BY 'password';
删除用户
drop user 用户名[,..]

drop user mouse@localhost;

9.2 权限管理

9.2.1 权限管理概述

MySql中权限表:

介绍
user 最重要的权限表,存储允许连接到服务器的账号。
db 存储用户对某个数据库的操作权限。
host 存储某个主机对数据库的操作权限。
tables_priv 对单个表进行权限设置。
columns_priv 对单个数据列进行权限设置。
proc_priv 对存储过程和存储函数进行权限设置。

重点补充:

  1. 表示对表进行操作的权限。包括Select /Insert /Update /Delete/ Create/ Drop / Grant / References / Index 和Alter

MySQL的访问控制的两个阶段

  1. 连接核实阶段
    用户试图连接MySQL服务器时,服务器基于用户提供的信息来验证用户身份。使用MySQL的user表进行身份核实
  2. 请求核实阶段
    对当前用户的每个操作都进行权限检查,判断用户是否有足够的权限来执行它。

在这里插入图片描述
权限的递进:先检查user表、然后db、host,再…直到conlumns_priv中都没有,就拒绝请求。

MySQL权限等级:

  1. 全局层级:适用于一个给定服务器中所有的数据库,权限存储于user
  2. 数据库层级:适用于一个给定数据库中的所有目标,权限在dbhost
  3. 表层级:适用于一个给定表中的所有列,权限在tables_priv
  4. 列层级:适用于一个给定表中的单一列,权限在columns_priv
  5. 子程序层级:适用于存储的子程序 ,可以被授权为全局层级和数据库层级,权限在proc_priv

MySQL权限类型

权限 含义
all[privileges] 设置除grant option之外的所有简单权限
alter 允许使用alter table
alter routine 更改或取消已存储的子过程
create 允许使用create table
create routine 创建已存储的子过程
create temporary table 允许使用create temporary table
create user 允许使用create user, drop user, rename,user 和 revoke all privileges
create view 允许使用create view
delete 允许使用delete
drop 允许使用drop table
execute 允许用户运行已存储的子程序
file 允许使用select…into outfile 和 load data infile
index 允许使用create index 和 drop index
insert 允许使用insert
lock tables 允许对用户拥有select权限的表使用lock tables
process 允许使用show full processlist
references 未被实施
reload 允许使用flush
replication client 允许用户询问从属服务器或主服务器的地址
replication slave 用于复制性从属服务器(从主服务器中读取二进制日志文件)
select 允许使用select
show databases 允许显示所有数据库
show view 允许使用show create view
shutdown show view MySQLadmin shutdown
super 允许使用change master,kill,purge masterlogs 和set global 语句;MySQLadmin debug命令;允许用户连接(一次),即使已达到max_connections;
update 允许使用update
usage “无权限”的同义词

9.2.2 权限管理语法

grant获取权限:
grant priv_type [(column_list)] //要设置的权限项;
[,priv_type[(column_list)]][,.....n] on
{tbl_name|*|*.*|db_name.*|db_name.tbl_name} //对象类型;
to user[,user][,....n]
[with grant_option] //可以将该用户的权限转移给其他用户;

在MySQL8以上,grant已经没办法创建新用户了

实例:
mysql> grant select on *.* to aa@localhost identified by '123' with grant option;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'identified by '123' with grant option' at line 1
mysql> grant select on *.* to mat@localhost with grant option;
Query OK, 0 rows affected (0.01 sec)

————————————————————————

revoke收回权限
revoke priv_type [(column_list)][,priv_type[(column_list)]][,.....n] on
{tbl_name|*|*.*|db_name.*|db_name.tbl_name}
from ‘username’@’hostname’[,‘username’@’hostname’][,...n]
实例:收回mat所有权限
mysql> revoke all privileges,grant option from mat@localhost;
Query OK, 0 rows affected (0.01 sec)

————————————————————————————————

查看用户权限
show grants for username@hostname
实践:查看mat的权限
mysql> show grants for mat@localhost;
+-----------------------------------------+
| Grants for mat@localhost                |
+-----------------------------------------+
| GRANT USAGE ON *.* TO `mat`@`localhost` |
+-----------------------------------------+
1 row in set (0.00 sec)

————————————————————————

限制权限
max_queries_per_hour count:表示每小时可以查询数据库的次数
max_connections_per_hour count:表示每小时可以连接数据库的次数
max_updates_per_hour count:表示每小时可以修改数据库的次数
实例:
grant all on *.* to test1@localhost 
with max_queries_per_hour 50
with max_connections_per_hour 10
with max_updates_per_hour 5;

————————————————————————————————————————
既然权限是存放在对应的表中,那么如果我们手动更新了权限表,是否MySQL服务器会自动立刻生效呢?如果不能,那使用什么方法可以让手动修改的权限生效呢?

9.3 备份与恢复

MySQL保证数据安全的三种方法:

  1. 数据库备份:通过导出数据或表文件的拷贝来保护数据
  2. 二进制日志文件:保存更新数据的所有语句
  3. 数据库复制:使用MySQL内部复制功能,建立在两个或两个以上的数据库之间的,通过设定它们的主次关系而实现的。

备份:将数据库中的结构、对象和数据导出,生成副本。
备份的分类:

  1. 按照备份时服务器是否在线:
    热备份:是指数据库在线服务正常的情况下进行数据备份。
    温备份:是指备份时数据库在线正常运行,但数据只能读不能写
    冷备份:是指数据库已经正常关闭的情况下进行备份。
  2. 按照备份的内容:
    逻辑备份:该文件格式与原数据库文件格式不同,通常备份的是SQL语句(也就是DDL和insert 语句)。
    物理备份:直接复制数据库文件进行备份,与逻辑备份相比,其速度快,但占用的存储空间比较大。
  3. 按备份涉及的数据范围:
    完整备份:备份整个数据库。增量备份与差异备份依赖于完整备份。
    增量备份:备份数据库从上一次完全备份或者最近一次增量备份以来改变的内容。
    差异备份:将从最近一次完整数据库备份以后发生改变的数据进行备份。

备份的时机:

  1. 创建数据库或为数据库填充数据后 备份数据库
  2. 创建索引后 备份数据库
  3. 清理事务日志后备份数据库,清理事务日志后 备份数据库
  4. 执行了无日志操作后备份数据库 备份数据库

9.3.1 备份方法

mysqldump命令的语法格式

mysqldump -u user -h host -ppassword

[--databases]databasename[,databasename2] //可以指定多个数据库;
[all-databases]//可以指定所有数据库;

[tablename=,[tablename=...]] //可以指定特定表;

> filename.sql //输出文件名,可以指定路径;
实例:
备份所有表:使用mysqldump备份数据库Course中所有的表。
mysqldump -u root -p Course > d:/backup/Course.sql

备份指定表:使用mysqldump备份数据库Course中的student表和teacher表。
mysqldump -u root -p Course student,teacher >d:/backup/Course_teacher_student.sql

备份多个指定数据库:使用mysqldump备份数据库Course 和mysql。
mysqldump -u root -p --databases Course,mysql >d:/backup/Course_mysql.sql

9.3.2 备份恢复

恢复数据库,就是让数据库根据备份的数据回到备份时的状态。主要的方法:

使用mysql命令恢复

mysql -u user -h host -ppassword databasename < filename.sql //注意箭头方向

使用mysql将备份文件Course.sql恢复到数据库Course2中。
mysql -u root -p Course2 < d:\backup\Course.sql

使用souce语句恢复

source filename.sql //需要进入到数据库后运行。

使用source命令将备份文件Course.sql恢复到数据库Course3中。
create course3;
use course3;
source d:\backup\Course.sql;

9.4 日志管理

日志是记录数据库日常操作和错误信息的文件,当数据遭遇意外发生丢失时可以通过日志文件来查询原因,并且通过日志文件进行数据恢复。

日志文件种类

  1. 错误日志
    记录MySQL数据库的启动,运行和停止时出现的问题,文本文件格式,默认开启
  2. 二进制日志
    记录了数据库中所有更改数据的语句,可用于修复数据库,二进制文件的格式,默认关闭。
  3. 通用查询日志
    记录用户登陆和记录查询的信息,文本文件格式,默认关闭。
  4. 慢查询日志
    记录所有执行时间超过long_query_time秒的查询或不使用索引的查询,文本文件格式,默认关闭。

详情
1、错误日志:
  默认是开启的,并且无法被禁止
  默认存储在MySQL数据库的数据库文件夹下。
  通常错误日志的文件名为“主机名.err”。
  可以通过修改配置选项log-err来更改。
 
通过修改配置选项log-error来更改路径和日志名:

[mysqld]
log-error[ =path/filename] #修改错误日志存放位置及文件名
查询错误日志位置
mysql> show variables like 'log_error';
+---------------+--------------------+
| Variable_name | Value              |
+---------------+--------------------+
| log_error     | .\HEARTFORLING.err |
+---------------+--------------------+
1 row in set, 1 warning (0.03 sec)
删除错误日志
mysqladmin -u root -p flush -logs
本质上是更新错误日志,创建出一个新的错误日志,旧的错误日志改名为:'原文件名.err-old'

2、二进制日志:
  默认是关闭的,通过修改my.ini配置文件的log-bin选项开启。

[mysqld]
log-bin[ =path/[filename]] #开启二进制日志
Expire_logs_days=10 #定义自动清除日志的时间(天数)
max_binlog_size=100M #定义单个二进制文件的大小限制
如何查看二进制日志?
mysqlbinlog XXXX-bin.0001
mysqlbinlog命令恢复数据库:

mysqlbinlog [option] filename mysql -u user -ppassword
option:可选参数,常见的参数有
--start-date (--stop-date) :用于指定数据库恢复的起始时间和结束时间点。
--start-position (--stop-position): 可以指定恢复数据库的开始位置和结束位置。
删除所有二进制日志
 reset master

删除指定的日志文件
可以根据编号或者创建的时间来删除,语法格式是:
purge {binary|master} logs to ‘log_name’
purge {binary|master} logs before ‘data

3、通用查询日志:
  默认是关闭的,通过修改my.ini配置文件的log选项开启。

[mysqld]
log[ =path/filename] #开启通用查询日志

4、慢查询日志:
  默认是关闭的,通过修改my.ini配置文件的log-slow- queries选项开启。

[mysqld]
log-slow-queries[ =path/filename] #开启慢查询日志
long_query_time = n #最慢的查询时间,单位是秒,默认值是10

9.5 事务处理

一个事务由一条或者多条SQL语句组成,这些SQL语句相互依赖不可分割,如果其中的某一条SQL语句没能完成,前面已经执行的SQL语句就会撤销,回滚到事务开始前的状态。

事务的四个特性(ACID):
原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。
隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。

9.5.1 MySQL事务类型

系统定义事务:
默认情况下,每条单独的语句都是一个事务。语句执行完后,MySQL会自动提交,也就是立刻将结果存储到磁盘中。如要显式关闭自动提交:使用的语句set @@autocommit=0;

用户定义事务:
用户自定义开始,结束,回滚和提交等事务的状态,用到的语句为:

start transaction |begin work:开启事务。
commit[ work] [and [no] chain] [[no] release]:提交事务
Rollback [work][and [no] chain] [[no] release]:回滚事务

会隐式地执行一个commit命令的语句:
drop database / drop table / create index /
drop index / alter table / rename table /
lock tables / unlock tables / set @@autocommit=1
rollback to 语句使事务回滚到某点,需要事先设置一个保存点:

设置保存点使用的语句
savepoint identifier
Rollback [work] to identifier

9.5.2 MySQL设置隔离级别

MySQL四种隔离级别:
序列化(SERIALIZABLE):用户之间通过一个接一个顺序地执行当前事务,这种方式提供了事务之间最大限度的隔离
可重复读(REPEATABLE READ):MySQL默认隔离级,适用于大多数应用程序。它确保同一事务内相同的查询语句执行结果一致。
提交读(READ COMMITTED):满足了隔离的简单定义,一个事务只能看见已提交事务所做的改变。
未提交读(READ UNCOMMITTED):提供了事务之间最小程度的隔离。这个级别下,所有事务都可以看到其他未提交事务的执行结果。

!隔离级别强度(从左到右减弱):序列化、可重复读、提交读、未提交读。

使用SET TRANSACTION 语句定义隔离级:
SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL
SERIALIZABLE |
REPEATABLE READ |
READ COMMITTED |
READ COMMITTED

9.5.3 MySQL事务并发

事务的并发,锁定的机制:
表级锁:一种特殊类型的访问,整个表被客户锁定。
页级锁:锁定表中的某几行(称作页)
行级锁:只有线程使用的行被锁定,其他行对于其他线程是可用的。

MySQL提供LOCK 语句来锁定当前线程的表,语法格式是:

LOCK TABLES table_name [as alias ] {
read [local] | # 用户可以读取表,但是不能修改表
[low_priority] write #只有锁定该表的用户可以修改表,其他的用户无法访问该表。
}


解除锁定:
UNLOCK Table//不需要指定表,会解锁所有表
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章