前言:
这篇文章会比较简单一些,也是一个锁的插播,主要的是MySQL中的行级锁和表级锁,主要就是两个内容,出于考虑,单独抽取出来了一篇文章,尽可能的区分
1.MySQL锁机制(行级)
2.MySQL锁机制(表级别)
3.线上数据库不稳定性的性能抖动优化实践
1.MySQL锁机制(行级)
1.1:首先要知道MySQL依靠什么防止脏写?
依靠锁机制让多个事务更新一行数据的时候串行化,避免同时更新一行数据。《避免脏写》,更新一行数据需要从磁盘中加载对应的数据页到buffer pool的缓存中(缓存页),才能进行更新,所以此时这行数据和关联的锁的数据结构,都是在内存中的,这里有个注意事项:代码中就算没有加事务,MySQL也是默认开启事务机制的,只是事务是否自动提交而已。《图解》
1.2:MySQL锁机制:共享锁和独占锁到底是什么?
1.2.1:Exclude独占锁
当一个事务加了独占锁之后,此时其他事务再要更新这行数据,都是要加独占锁的,但是只能生成独占锁排队公平等待。那么当有事务在更新数据的时候,其他的事务可以读取这行数据吗?默认情况下会加锁吗?
《不会加锁,当有事务在更新的时候,事务B进去读取数据的时候默认是开启MVCC机制》
1.2.3:share mode共享锁
如果有需求在执行查询到操作的时候,需要加锁也是ok的,MySQL支持共享锁,语法:select * from table lock inshare mode,意思就是查询的时候对一行数据加共享锁,但是如果此数据行已经加了独占锁,同样能加共享锁了,不相互互斥。 【互斥关系图解】
2.MySQL锁机制(表级别)
2.1:在执行DDL语句的时候,例如alter table之类的语句,会阻塞所有的增删改操作,执行增删改的时候,会阻塞DDL操作。但这是通过MySQL通用的元数据锁实现的,也就是metadata Locks,因为表锁其实是innoDB存储引擎的概念,innoDB存储引擎提供了自己的表级锁,和这里的DDL语句用的元数据锁还不是一个概念。只不过DDL语句和增删改操作确实是互斥的。2.2:MySQL中是如何加表锁的?MySQL的表锁,几乎很少用到
,分为两种:一种表级共享锁,一种表级独占锁
3:线上数据库不稳定性的性能抖动优化实践
前言:大量的buffer pool缓存页刷盘,导致MySQL数据库性能抖动。
3.1:大量数据页加载到数据库内存中,因为lru算法,可能会导致大量缓存页会flush刷盘。
------ 解决方案:最核心的就是将innodb_io_capacity设置为SSD固态硬盘的IOPS,提高缓存页flush的速度,同时设置innodb_flush_neighbors为0,让flush机制别刷临近缓存页,减少要刷缓存页的数量
3.2:可能还会出现的抖动问题就是:redo log buffer pool 刷盘的时候,如果需要覆盖第一个redo log文件时,会让第一个文件的缓存页进行刷盘,此时也会hang住数据库出现MySQL数据的抖动问题;