锁具体说明

latch 多线程访问内存数据结构,时间短,无死锁检测,有mutex和rwlock两种(类似java的synchronized,代码中的)使用
show engine innodb mutex;

lock 事务访问数据库对象,一般commit或rollback释放,有死锁检测处理

row/page/table,共享S/排它X(删除,插入,更新), 意向(IX,IS,指对小粒度加锁,对大粒度元素加意向锁)
innodb (行锁,表级意向锁)
查看:
show engine innodb status;
information_schema.INNODB_TRX(事务),INNODB_LOCKS(锁),INNODB_LOCK_WAITS(哪个事务在等哪个事务的哪把锁)

一致性非锁定读
数据有内存版本,多个快照版本(undo)
read committed: 永远读最新版本,优先读内存版本,若有X锁,读最新快照版本
repeatable read: 第一次(优先读内存版本,若有X锁,读最新快照版本)
后面读取 (永远读第一次读到的版本),rr在非锁定读一样不存在幻读问题
MVCC,提高并发性

一致性锁定读
lock in share mode/for update (必须在事务中,insert,update或delete也加X锁)

自增锁
mysql中只能有1个自增列,自增列必须是索引,且为索引的第一列。
select max(auto_inc_column) from t for update 用于初始化内存中计数器值,自增锁锁住计数器(特殊的表级锁:并不是说锁住表了,而是单表只有一个自增锁,导致其他在当前表进行插入的事物等待),计数器加1,插入,插入完成或失败释放锁(不是在事务结束后释放)
并发插入的性能问题,引起锁等待问题

外键与锁
子表插入或更新时,会查询父表是否存在记录 (select… lock in share mode),查不到错误,也可能锁等待
为什么加S锁?若父表删除这条记录,但未提交,子表非锁定读读到了记录并完成子表插入,父表提交后就会存在不一致情况。

repeatable read 下用next key locking(record lock+gap lock)解决幻读问题,达到sql标准的Seriazliable级别。
分析锁问题很复杂
1 考虑隔离级别(rc下没有所谓的gap lock,这个只有rr才有)
read committed (总归是保证读最新的提交过的数据)和 repeatable read (总归是保证多次读结果一致)
2 考虑是否加锁,是select(不加),share mode/for update/insert/update/delete 才有锁
3 考虑在哪里加锁,通过主键查询加在主键记录上,通过索引查询(X锁主键和索引都加X锁,S锁索引加S锁但主键不加锁),非索引查询-全表扫描加表锁(实际是覆盖所有行的next key lock)
4 考虑是否加gap lock,是否存在范围级别查询(secondary_index=value也存在范围查询,因为可能查到多个记录,可能会存在插入新记录的情况,一般secondary_index为唯一索引的等值查询和主键索引的等值查询无范围查询)
5 考虑gap lock锁定的范围,N条记录,N+1个范围
等值的gap lock锁等值记录和内部周围范围,
范围的gap lock锁范围内M条记录和M+1个gap,gap永远没有半个,即有些超出范围的记录也无法插入

脏读:读到未提交数据(一般不允许)
读到脏页(很正常,事务提交脏页也可能没刷新,checkpoint刷)
不可重复读(偏向于读到的数据不被修改,如果加锁自然可以,不加锁就永远读第一次的版本(自然就没有幻读的概念))
幻读(非锁定的rr偏向于不读出新数据,锁定的rr使用 next key locking (gap lock) 解决幻读)
丢失更新:更新一般都加X锁,不会直接被覆盖,但逻辑上存在(先查后更,查完被别人更新了)

阻塞:
innodb_lock_wait_timeout
innodb_rollback_on_timeout(默认不回滚) ,绝大多数异常都不回滚,死锁回滚
(注意java程序的处理,一般程序报异常,我们再决定commit or rollback,如spring回滚rt和error)

死锁:多事务互相等待(竞争锁资源)
解决思路:rollback某个事务(让其释放锁)并让其重新开始,另一个在rollback时就获取资源进行下去了
方式1 锁等待超时触发回滚(要设置innodb_rollback_on_timeout),问题谁先超时谁回滚(一般是先开始等的那个),而我们需要回滚影响最小的(权重最少,改动最少,undo最少)
方式2 innodb 用的是wait-for graph(更为主动)
在这里插入图片描述

t1事务等待t2的锁(t1指向t2) t2事务等待t1的锁(t2指向t1) 存在回路,死锁
rollback undo量最小事务

锁升级 (多条row lock 升级page lock,或多page lock 升级table lock)
innodb 不支持锁升级
推测:页用位图标识其中记录是否有加锁,事务用链表串联其加的所有锁。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值