根据锁的范围,Mysql大致可以分为全局锁,表级锁和行锁三类
全局锁
命令是:Fush tables with read lock (FTWRL)
使用场景是做没有事务的引擎做全库备份
官方自带备份工具:mysqldump,使用参数-single-transaction,启动一个事务,由mvcc支持保证事务一致性.
表级锁
表锁
语法:lock tables …read/write
该锁粒度比较大,锁表影响较高.
元数据锁 MDL
mysql5.5新增的metadata lock,非显示使用
对表做增删改查的时候会加上读锁,表结构发生改变的时候会加写锁
读锁不互斥,读写,写写互斥
有写锁的时候会导致后续的读锁阻塞,在高并发的时候会导致数据库不能用
在加写锁的时候注意kill前面的长事务,并为这个写锁加上等待时间.到时自动释放,通过重复命令来修改表结构.
行锁
两阶段提交
行锁是在需要的时候加上的,事务结束的时候才释放.
所以在事务中需要加多个行锁,要把可能造成锁冲突\最可能影响并发度的锁往后放.
死锁和死锁检测
不同事务相互等待对方的资源释放,就是进入死锁状态
解决策略:
- 加入超时等待机制:innodb_lock_wait_time 默认50s,过小的话会导致误判.所以一般不采用.
- 发起死锁检查:innodb_deadlock_detect = on (默认是on) 会有额外负担,高并发的时候需要消耗大量CPU资源
解决热点行更新导致的性能问题:
确保业务不会出现死锁,可以临时关闭死锁检查
控制并发:1中间件 2修改源码(同行更新在进入引擎前排队) 3单行改成逻辑多行来减小并发.(会引发其他问题,需要额外代码来解决)
