数据库锁
全局锁
- FTWRL前有读写的话 ,FTWRL都会等待 读写执行完毕后才执行 FTWRL 执行的时候要刷脏页的数据到磁盘,因为要保持数据的一致性 ,理解的执行FTWRL时候是所有事务都提交完毕的时候.
- mysqldump + -single-transaction 也是保证事务的一致性,但他只针对 有支持事务引擎,比如innodb 所以还是强烈建议大家在创建实例,表时候需要innodb引擎为好
- 全库只读 readonly = true 还有个情况在 slave 上 如果用户有超级权限的话 readonly 是失效的
表级锁
- a.表级别锁 :一个直接就是表锁 lock table 建议不要使用, 影响太大,另个就是 MDL 元数据锁
- b.MDL 是并发情况下维护数据的一致性,在表上有事务的时候,不可以对元数据经行写入操作,并且这个是在server层面实现的
- 当你做 dml 时候增加的 MDL 读锁, update table set id=Y where id=X; 并且由于隔离级别的原因 读锁之间不冲突
- 当你DDL 时候 增加对表的写锁, 同时操作两个alter table 操作 这个要出现等待情况。
- 但是如果是dml与ddl之间的交互 就更容易出现不可读写情况,这个情况容易session爆满,session是占用内存的,也会导致内存升高 MDL 释放的情况就是事务提交.
行锁
- 两阶段锁:在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。
建议:如果你的事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。 死锁:当并发系统中不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源时,就会导致这几个线程都进入无限等待的状态。
- 解决方案:
- 通过参数 innodb_lock_wait_timeout 根据实际业务场景来设置超时时间,InnoDB引擎默认值是50s。
- 发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑(默认是开启状态)。 如何解决热点行更新导致的性能问题?
- 如果你能确保这个业务一定不会出现死锁,可以临时把死锁检测关闭掉。一般不建议采用
- 控制并发度,对应相同行的更新,在进入引擎之前排队。这样在InnoDB内部就不会有大量的死锁检测工作了。
- 将热更新的行数据拆分成逻辑上的多行来减少锁冲突,但是业务复杂度可能会大大提高。 innodb行级锁是通过锁索引记录实现的,如果更新的列没建索引是会锁住整个表的。