详解MySQL(InnoDB)如何处理死锁

详解MySQL(InnoDB)如何处理死锁,第1张

锁是需要事务结束后才释放的。

一个是 MVCC,一个是两阶段锁协议。

为什么要并发控制呢?是因为多个用户同时 *** 作 MySQL 的时候,为了提高并发性能并且要求如同多个用户的请求过来之后如同串行执行的一样(为了解决脏读、不可重复读、幻读)

官方定义:

两阶段锁协议是指所有事务必须分两个阶段对数据加锁和解锁,在对任何数据进行读、写 *** 作之前,事务首先要获得对该数据的封锁;在释放一个封锁之后,事务不再申请和获得任何其他封锁。

对应到 MySQL 上分为两个阶段:

但是两阶段锁协议不要求事务必须一次将所有需要使用的数据加锁(innodb在需要的索引列数据才锁行),并且在加锁阶段没有顺序要求,所以这种并发控制方式会形成死锁。

MySQL有两种死锁处理方式:

死锁检测 (默认开启)

死锁检测的原理是构建一个以事务为顶点、锁为边的有向图,判断有向图是否存在环,存在即有死锁。

回滚

检测到死锁之后,选择插入更新或者删除的行数最少的事务回滚,基于 INFORMATION_SCHEMAINNODB_TRX 表中的 trx_weight 字段来判断。

收集死锁信息:

减少死锁:

死锁解决:

每个使用关系型数据库的程序都可能遇到数据死锁或不可用的情况,而这些情况需要在代码中编程来解决;本文主要介绍与数据库事务死锁等情况相关的重试逻辑概念,此外,还会探讨如何避免死锁等问题,文章以DB2(版本9)与为例进行讲解。

什么是数据库锁定与死锁

锁定(Locking)发生在当一个事务获得对某一资源的“锁”时,这时,其他的事务就不能更改这个资源了,这种机制的存在是为了保证数据一致性;在设计与数据库交互的程序时,必须处理锁与资源不可用的情况。锁定是个比较复杂的概念,仔细说起来可能又需要一大篇,所以在本文中,只把锁定看作是一个临时事件,这意味着如果一个资源被锁定,它总会在以后某个时间被释放。而死锁发生在当多个进程访问同一数据库时,其中每个进程拥有的锁都是其他进程所需的,由此造成每个进程都无法继续下去。

如何避免锁

我们可利用事务型数据库中的隔离级别机制来避免锁的创建,正确地使用隔离级别可使程序处理更多的并发事件(如允许多个用户访问数据),还能预防像丢失修改(LostUpdate)、读“脏”数据(DirtyRead)、不可重复读(NonrepeatableRead)及“虚”(Phantom)等问题。

隔离级别问题现象

丢失修改读“脏”数据不可重复读“虚”

可重复读取NoNoNoNo

读取稳定性NoNoNoYes

光标稳定性NoNoYesYes

未提交的读NoYesYesYes

表1:DB2的隔离级别与其对应的问题现象

在只读模式中,就可以防止锁定发生,而不用那些未提交只读隔离级别的含糊语句。昌平电脑培训发现一条SQL语句当使用了下列命令之一时,就应该考虑只读模式了

exec sp_lock 快捷键 C_2

exec sp_who active exec sp_who快捷键 C_1

用Profiler里面的Locks->Deadlock graph 监控看看,如果看到了死锁图,就可以比较形象地展现死锁发生的过程,还可以看到锁的具体类型和过程里面的语句,对你诊断会有帮助。

Declare @LockTab table( spid int,dbid int ,ObjId int,IndId int ,Type varchar(50),Resource varchar(50),Mode varchar(50),Status varchar(50))

insert into @LockTab exec sp_lock

Declare @ActiveTab table(spid int,ecid int,status varchar(50),loginname varchar(50),hostname varchar(50),blk int,dbname varchar(50),cmd varchar(50),request_id int)

insert into @ActiveTab exec sp_who active

select from @LockTab lt

left join @ActiveTab at on ltspid=atspid

怎么解除SQL Server死锁的问题SQL Server死锁是我们经常会碰到的问题,下面就为您介绍如何查询SQL Server死锁,希望对您学习SQL Server死锁方面能有所帮助。   

SQL Server死锁的查询方法:    exec masterdbop_lockinfo 0,0 ---显示死锁的进程,不显示正常的进程    exec masterdbop_lockinfo 1,0 ---杀死死锁的进程,不显示正常的进程   

SQL Server死锁的解除方法:    Create proc p_lockinfo    @kill_lock_spid bit=1, --是否杀掉死锁的进程,1 杀掉, 0 仅显示    @show_spid_if_nolock bit=1 --如果没有死锁的进程,是否显示正常进程信息,1 显示,0 不显示    as    declare @count int,@s nvarchar(1000),@i int    select id=identity(int,1,1),标志,    进程ID=spid,线程ID=kpid,块进程ID=blocked,数据库ID=dbid,   

数据库名=db_name(dbid),用户ID=uid,用户名=loginame,累计CPU时间=cpu,    登陆时间=login_time,打开事务数=open_tran, 进程状态=status,    工作站名=hostname,应用程序名=program_name,工作站进程ID=hostprocess,    域名=nt_domain,网卡地址=net_address    into #t from(    select 标志='死锁的进程',    spid,kpid,ablocked,dbid,uid,loginame,cpu,login_time,open_tran,    status,hostname,program_name,hostprocess,nt_domain,net_address,   

s1=aspid,s2=0    from mastersysprocesses a join (    select blocked from mastersysprocesses group by blocked    )b on aspid=bblocked where ablocked=0    union all    select '|_牺牲品_>',    spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran,    status,hostname,program_name,hostprocess,nt_domain,net_address,    s1=blocked,s2=1    from mastersysprocesses a where blocked<>0    )a order by s1,s2    select @count=@@rowcount,@i=1    if @count=0 and @show_spid_if_nolock=1    begin    insert #t    select 标志='正常的进程',    spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time,    open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address    from mastersysprocesses    set @count=@@rowcount    end    if @count>0    begin    create table #t1(id int identity(1,1),a nvarchar(30),b Int,EventInfo nvarchar(255))    if @kill_lock_spid=1    begin    declare @spid varchar(10),@标志 varchar(10)    while @i<=@ count    begin    select @spid=进程ID,@标志=标志 from #t whereid=@ i    insert #t1 exec('dbcc inputbuffer(')')    if @标志='死锁的进程' exec('kill'+@ spid)    set @i=@i+1    end    end    else    while @i<=@ count    begin    select @s='dbcc inputbuffer('+cast(进程ID as varchar)+')' from #t whereid=@ i    insert #t1 exec(@s)    set @i=@i+1    end    select a,进程的SQL语句=bEventInfo    from #t a join #t1 b on aid=bid    end

每个使用关系型数据库的程序都可能遇到数据死锁或不可用的情况,而这些情况需要在代码中编程来解决;本文主要介绍与数据库事务死锁等情况相关的重试逻辑概念,此外,还会探讨如何避免死锁等问题,文章以DB2(版本9)与为例进行讲解。

什么是数据库锁定与死锁锁定(Locking)发生在当一个事务获得对某一资源的“锁”时,这时,其他的事务就不能更改这个资源了,这种机制的存在是为了保证数据一致性;在设计与数据库交互的程序时,必须处理锁与资源不可用的情况。

锁定是个比较复杂的概念,仔细说起来可能又需要一大篇,所以在本文中,只把锁定看作是一个临时事件,这意味着如果一个资源被锁定,它总会在以后某个时间被释放。

而死锁发生在当多个进程访问同一数据库时,其中每个进程拥有的锁都是其他进程所需的,由此造成每个进程都无法继续下去。

如何避免锁我们可利用事务型数据库中的隔离级别机制来避免锁的创建,正确地使用隔离级别可使程序处理更多的并发事件(如允许多个用户访问数据),还能预防像丢失修改(LostUpdate)、读“脏”数据(DirtyRead)、不可重复读(NonrepeatableRead)及“虚”(Phantom)等问题。

隔离级别问题现象丢失修改读“脏”数据不可重复读“虚”可重复读取NoNoNoNo读取稳定性NoNoNoYes光标稳定性NoNoYesYes未提交的读NoYesYesYes表1:DB2的隔离级别与其对应的问题现象在只读模式中,就可以防止锁定发生,而不用那些未提交只读隔离级别的含糊语句。

山西电脑培训>

db2 get snapshot for locks on sample

db2 get db cfg for sample

db2 update db cfg using dlchktime 10000

-查看数据库管理器级别快照信息

db2 get snapshot for dbm

-查看数据库级别快照信息

db2 get snapshot for database on dbname

-查看应用级别快照信息

db2 get snapshot for application agentid appl-handler

注:appl-handler可以从list applicaitions的输出中得到

-查看表级别快照信息

db2 get snapshot for tables on dbname

注:需要把tables快照开关设为ON才会有作用

-查看锁快照信息

db2 get snapshot for locks on dbname

db2 get snapshot for locks on for application agentid appl-handler

-查看动态sql语句快照信息

db2 get snapshot for dynamic sql on dbname

db2 get monitor switches

db2 update monitor switches using lock on statement on

create event monitor mymonitor for deadlocks,statements write to file 'c:/temp'

set event monitor mymonitor state 1

db2evmon - path 'c:/temp'

--转自:>

以上就是关于详解MySQL(InnoDB)如何处理死锁全部的内容,包括:详解MySQL(InnoDB)如何处理死锁、昌平电脑培训分享在Java程序中处理数据库超时与死锁、怎么查看数据库死锁,和解决方法等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9327523.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存