数据库系列 - MySQL用户权限以及死锁排查

参看:

  • 《MySQL必知必会》
  • https://www.cnblogs.com/Richardzhu/p/3318595.html

一、MySQL用户权限

最近有一个项目,在开发过程中直接把数据库安装到阿里云服务器,本地连接阿里云服务器中的MySQL就不能直接root用户连接,而每次数据库操作都要使用新建的用户与用户进行交互操作。

在使用非root用户的时,执行本地的sql文件,就需要一些权限,比如 SELECT,INSERT,UPDATE,DELETE,CREATE 等等权限,下面就以此做一份笔记,之后在开发的时候,就可以查看此文章的记录,直接进行应用即可。
添加MySQL用户并设置权限的好处:新的SQL用户不允许访问访问属于其他SQL用户的库或表,甚至不能使用SELECT语句。新的SQL用户必须显式的被授予权限,才能执行对应的操作。

二、用户权限介绍

1.权限级别

  • 全局:可以管理整个MySQL
  • 数据库:可以管理指定的数据库
  • 数据表:可以管理指定数据库的指定表
  • 字段:可以管理指定数据库的指定表的指定字段

权限存储在mysql库的user,db,tables_priv,columns_priv,procs_priv这几个系统表中,待MySQL实例启动后就加载到内存中,实现用户的权限控制。

2.权限实现

MySQL权限实现分为两段验证:

第一阶段:服务器首先会检查此用户是否允许连接。先从user表中的Host,User,Password这3个字段中判断连接的ip、用户名、密码是否存在,存在则通过验证。

第二阶段:通过身份验证后,用户发起的每个请求都需要进行权限判断,按照 user,db,tables_priv,columns_priv,procs_priv 的顺序进行验证。即先检查全局权限表user,如果user中对应的权限为Y,则此用户对所有数据库的权限都为Y,将不再检查db, tables_priv,columns_priv;如果为N,则到db表中检查此用户对应的具体数据库,并得到db中为Y的权限;如果db中为N,则检查tables_priv中此数据库对应的具体表。以此类推。

3.权限分布

MYSQL的权限如何分布,就是针对表可以设置什么权限,针对列可以设置什么权限等等,这个可以从官方文档中的一个表来说明:

权限分布 可能的设置的权限
表权限 ‘Select’, ‘Insert’, ‘Update’, ‘Delete’, ‘Create’, ‘Drop’, ‘Grant’, ‘References’, ‘Index’, ‘Alter’
列权限 ‘Select’, ‘Insert’, ‘Update’, ‘References’
过程权限 ‘Execute’, ‘Alter Routine’, ‘Grant’

以上也是我们最常用的一些权限。更多的权限设置,直接查看官方文档中对权限的描述即可。

4.查询权限表

查看用户MySQL用户

select user,host from mysql.user;

查看root用户在权限表中的权限

前一个表为N,系统才会去检查下一个表。

# Y表示有权限 ,N表示无权限
# 1.mysql.user表 (all)
select * from mysql.user where user='root';

# 2.mysql.db表 (empty)
select * from mysql.db where user='root';

# 3.mysql.tables_priv (empty)
select * from mysql.tables_priv where user='root';

# 4.mysql.colums_priv表 (empty)
select * from mysql.columns_priv where user='root';

# 5.mysql.procs_priv (empty)
select * from mysql.procs_priv where user='root';

三、用户权限实战

以下所有操作都是以为root用户,在mysql库中进行。

1.查看用户权限信息

查看当前用户

select user();

查看MYSQL有哪些用户

select user,host from mysql.user;

查看已经授权给用户的权限信息

show grants for 'pdh'@'%';

2.用户创建和授权

简单说一下MySQL的授权用户组成: ‘user_name’@‘host_name’(中间使用@符号连接)。其中user_name表示用户名,host_name表示主机,可以是ipv4和ipv6格式的,%表示所有主机均可访问。下面列举一下不同的格式表示不同的主机:

项目 Value qq
user_name host_name 说明
‘pdh’ ‘198.51.100.177’ pdh,只能从此ip连接
‘pdh’ ‘198.51.100.%’ pdh,从198.51.100 子网中的任何主机
‘pdh’ ‘%’ pdh,任何主机可连

创建MySQL用户和权限*

# 1.使用CREATE创建用户,后再授权
# 1.1 创建 pdh 用户,设置密码为123456,并没有权限
CREATE USER 'pdh'@'%' IDENTIFIED BY '123456';
# 1.2 授予pdh查询和添加test库的权限
grant select,insert,update,delete,create,alter on test.* to 'pdh';

# 2.使用GRANT创建用户并授权test库的所有操作
grant all privileges on test.* to 'pdh'@'%' identified by "123456" with grant option;

以上指令说明

1. ALL PRIVILEGES 是表示所有权限,你也可以使用select、update等权限。
2. ON 用来指定权限针对哪些库和表
3. test.*  表示test库的所有表
4. TO 表示将权限赋予某个用户。
5. 'pdh'@'%' 表示pdh用户,主机为%。主机可以是IPIP段、域名以及%
6. IDENTIFIED BY 指定用户的登录密码
7. WITH GRANT OPTION 这个选项表示该用户可以将自己拥有的权限授权给别人

刷新权限
使用这个命令使权限生效,对权限表user、db、host等做了update或者delete更新的时候务必执行权限刷新。

flush privileges;

查看和修改权限
查看当前用户权限

show grants;

回收权限

# 回收alter权限
revoke alter on test.* from 'pdh'@'%';
# 回收所有权限
revoke all privilegeson test.* from 'pdh'@'%';

注意DDL语句是不支持回滚的
DDL (Data Definition Language 数据定义语言)
create table 创建表
alter table 修改表
drop table 删除表
truncate table 删除表中所有行
create index 创建索引
drop index 删除索引
当执行DDL语句时,在每一条语句前后,oracle都将提交当前的事务。如果用户使用insert命令将记录插入到数据库后,执行了一条DDL语句(如create table),此时来自insert命令的数据将被提交到数据库。当DDL语句执行完成时,DDL语句会被自动提交,不能回滚。

DML (Data Manipulation Language 数据操作语言)
insert 将记录插入到数据库
update 修改数据库的记录
delete 删除数据库的记录
当执行DML命令如果没有提交,将不会被其他会话看到。除非在DML命令之后执行了DDL命令或DCL命令,或用户退出会话,或终止实例,此时系统会自动发出commit命令,使未提交的DML命令提交。

四、误删oracle数据库中的数据,在不考虑全库备份和利用归档日志情况,怎样快速恢复数据呢?

下面介绍3种方法。

1. 利用oracle提供的闪回方法进行数据恢复,适用于delete删除方式

首先获取删除数据的时间点:

select * from v$sql where sql_text like '%table_name%' ;

根据结果中的sql_text内容,找到delete执行语句对应的删除时间点,执行下面语句查询出删除的数据。

select * from table_name as of timestamp to_timestamp(‘删除时间点’,‘yyyy-mm-dd hh24:mi:ss’)
where (删除时的条件)

2. 利用oracle虚拟回收站功能

原理是因为oracle数据库在删除表时会将删除信息存放于某虚拟回收站中而非直接清空,在此种状态下数据库标记该表的数据库为可以复写,所以在该块未被重新使用前依然可以恢复数据。该方法多用于drop删除
首先查询user_table视图,找到被删除的表:

select table_name,dropped from user_tables;
select object_name,original_name,type,droptime from user_recyclebin;

注意此时的,object_nameoriginal_name就是回收站存放的表名和原来删除的表名,如果表名没有被重新命名,可以通过下面语句进行恢复:

flashback table original_name to before drop;

如果不知道源表名,或者需要重新命名新的表名存放数据,则可以通过回收站中的object_name进行恢复,命令如下:

flashback table object_name to before drop new_table_name;

3. 用oracle数据库的闪回功能可以将数据库恢复到过去某一状态

注意,此时是整库恢复,具体语法如下:

SQL>alter database flashback on
SQL>flashback database to scn SCNNO;
SQL>flashback database to timestamp to_timestamp(‘frombyte 2021-09-02 23:59:59,‘yyyy-mm-dd hh24:mi:ss’);

4. 彻底删除数据

如果确定需要删除的数据又不想无谓的占用空间,我们可以使用以下3种方式:

  • 采用truncate方式进行截断。(不能进行数据回恢复)
  • drop时加上purge选项:drop table table_name purge
  • 通过删除recyclebin区域来永久性删除表 ,drop table table_name cascade constraints purge table table_name;

5. 关于清空回收站

  1. 删除当前用户回收站

    purge recyclebin;

  2. 删除全体用户在回收站的数据

    purge dba_recyclebin;

select * from INFORMATION_SCHEMA.METADATA_LOCK_INFO;

五、查看死否死锁

mysql版本不同。 命令不同。

1、mysql5.7 查看死锁

Mysql 查询是否存在锁表有多种方式,这里只介绍一种最常用的。

1、查看正在进行中的事务
SELECT * FROM information_schema.INNODB_TRX
2、查看正在锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
3、查看等待锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
4、查询是否锁表
SHOW OPEN TABLES where In_use > 0;
在发生死锁时,这几种方式都可以查询到和当前死锁相关的信息。

5、高斯数据库查看元数据锁
select * from INFORMATION_SCHEMA.METADATA_LOCK_INFO;

select * from information_schema.processlist where id = '6086136' or id = '8620342';


5、查看最近死锁的日志
show engine innodb status

2、mysql8.0 查看死锁

Mysql 查询是否存在锁表有多种方式,这里只介绍一种最常用的。

1、查看正在进行中的事务
SELECT * FROM information_schema.INNODB_TRX
2、查看正在锁的事务
SELECT * FROM performance_schema.data_locks;
3、查看等待锁的事务
SELECT * FROM performance_schema.data_lock_waits;
4、查询是否锁表
SHOW OPEN TABLES where In_use > 0;
在发生死锁时,这几种方式都可以查询到和当前死锁相关的信息。

5、高斯数据库查看元数据锁
SELECT * FROM performance_schema.metadata_locks;

select * from performance_schema.processlist where id = '6086136' or id = '8620342';


5、查看最近死锁的日志
show engine innodb status
SHOW PROCESSLIST;

在 MySQL 中,使用 SHOW PROCESSLIST 命令可以列出当前正在运行的线程(包括连接、查询等)。这可以帮助你查看当前数据库中的活动进程,并对其进行分析和管理。当然,执行该命令需要相应的权限。

通过运行 SHOW PROCESSLIST,你可以看到当前活动的连接、执行的查询以及它们的状态等信息。这对于识别潜在的性能问题或者了解数据库的整体情况非常有用。

你可能感兴趣的:(数据库系列专题,mysql,数据库)