关于数据库死锁

不锁怕出事,锁了又怕锁死了!!!

数据库由于数据存储速度快,数据稳定,结构化的特性,被广泛用作数据存储,并成为最重要,最常见的方式!

数据库从20世纪50年代诞生伊始,就因为支持事务的特性得到大力的发展,最终各种数据库诸如oracle,Sybase,mysql等关系型数据库百花齐放,既然数据库是因为事务而生,那么事务的特性又是哪些呢?

简而言之就是ACID(原子性,一致性,隔离性,持久性)! 而为了保持数据的一致性,数据库都有了一个操作叫做加锁!有表级锁,行级锁,页面锁!

死锁就是说两个线程在争同一个资源,然后互不相让,导致锁死的情况(比如两个人从两端走上独木桥,然后卡死在桥中间)!

回到问题本身,数据库在什么时候会产生死锁呢?

1,情况一:我中有你,你中有我!

事务一:两个操作update A;update B;

事务二:两个操作update B;update A;

线程一执行事务一到一半的时候,锁了A想要获得B的锁,与此同时事务二执行到了锁B,想要获得锁A的时候,因为互相都想要对方拥有的锁,而导致死锁!

2,情况二:吃着碗里的,看着锅里的!

A线程先查询了一条记录(使用了共享锁),与此同时B线程正要修改这条记录(使用了独占锁),然后A线程突然想修改这条记录了,怎么办呢?升级锁。。

而B线程想要降级为共享锁,必须要等到A线程释放掉共享锁,这样就形成了死锁!可以看到这个过程中是A占着共享锁想要升级,B占着独占锁想要降级,然后卡死!

3,牵一发而动全身!

一个表结构,必须要有适当的索引等优化手段,如果在执行事务的时候,没有加索引条件甚至没有任何条件,那么将执行全表扫描,如果是多个事务在操作,很容易就发生了阻塞和死锁!所以字段加索引非常重要!!

 
数据库死锁的解决方案。

1)以固定的顺序访问表和行。即按顺序申请锁,这样就不会造成互相等待的场面。

2)大事务拆小。大事务更倾向于死锁,如果业务允许,将大事务拆小。

3)在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概率。

4)降低隔离级别。如果业务允许,将隔离级别调低也是较好的选择,比如将隔离级别从RR调整为RC,可以避免掉很多因为gap锁造成的死锁。

5)为表添加合理的索引。如果不走索引将会为表的每一行记录添加上锁,死锁的概率大大增大。

 

使用navicat测试学习:
首先使用set autocommit = 0;(取消自动提交,则当执行语句commit或者rollback执行提交事务或者回滚)

查询 正在执行的事务:
SELECT * FROM information_schema.INNODB_TRX;

可以使用mysql命令:kill  线程id       杀掉线程

查询mysql数据库中还可以使用:

查看正在锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS; 
查看等待锁的事务

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
查询mysql数据库中存在的进程

select * from information_schema.`PROCESSLIST`(show processlist;) 

select concat('KILL ',id,';') from information_schema.processlist where user='root';

 

1、通过SHOW FULL PROCESSLIST命令查看:

2、通过查询链接线程相关的表来查看快照

select id, db, user, host, command, time, state, info
from information_schema.processlist
order by time des

3、通过navicat中的【工具】=> 【服务器监控】进行查看结果:

 

-- 查询非 Sleep 状态的链接,按消耗时间倒序展示,自己加条件过滤
select id, db, user, host, command, time, state, info
from information_schema.processlist
where command != 'Sleep'
order by time desc 

kill 使用

把拼接 kill 的执行结果跑一遍就搞定了,这个有时候非常好用,谁用谁知道

-- 查询执行时间超过2分钟的线程,然后拼接成 kill 语句
select concat('kill ', id, ';')
from information_schema.processlist
where command != 'Sleep'
and time > 2*60
order by time desc

 

posted @ 2022-02-28 09:25  人生苦短,知足常乐!  阅读(200)  评论(0编辑  收藏  举报