一、latch锁是什么锁?mysql
二、latch锁是如何保护list?sql
三、latch争用的现象和过程?并发
四、latch何时会产生严重的争用?oop
五、如何监控latch争用状况?优化
六、如何确认latch争用类型?spa
七、如何下降latch争用?线程
一、定义code
latch锁是内存锁,是一个小型的在内存中保护list的内存锁结构。blog
二、特色
一、不排队
二、spin,一个线程想得到一个锁,可是该锁已被另外一线程持有,进行spin(空转随机时间)占用cpu间接性的等待锁的释放,而后获取去进行相关操做。
三、os waits:sleep,spin屡次仍然spin
四、cpu繁忙,latch争用
Q:什么是锁?
A:
一、用来保护共享资源,支持并发
二、锁会影响并发
三、latch锁、lock锁
一、“保护”过程分析
一、访问页先须要访问链
二、修改list不等于修改页
三、何时修改list
一、物理读,将数据页挂到list上
二、内存读、修改数据页,修改链
四、锁,其实就是一个内存空间,有结构有数据的内存数据块
s:R共享锁
x:W排它锁
五、锁的兼容性
一、但凡是有x锁,排它,就不兼容。
二、latch锁排它就会形成latch争用。
注:mutex互斥锁:针对并发量不是很大的资源。
二、原理图分析
一、latch争用现象
一、latch争用会表现为cpu繁忙
二、latch争用没有排队,等一段随机的时间再回来看一看
二、latch争用过程
一、链上有一个链的保护机制latch,小内存结构;
二、这时候有读的线程A上来要读取链,这个时候这个管理就变成r(读锁),当在链上找到数据页的时候(读),一找到就释放读锁;
三、B上来也要读取,这个时候一看是r,读锁是能够共享的,它也对链进行访问读取;
四、C上来要修改链中的两个块的内容,一看是r,r和w是互斥的,不能同时进行,要么
一、主动要求退出cpu;
二、空占着cpu资源(执行一段空代码,loop,隔一段时间看看A和B有没有使用完(spin),可是在这个过程当中由于C没有排队等待,因此可能在等待的过程当中又有其余的线程上来霸占链(不排队的坏处),若是执行屡次仍这样,可能就sleep,退出cpu了,sleep,产生os waits)。
五、为何空占(惧怕os看它闲着把它强行拖出去)
六、等(由于它知道A和B占用资源时间比较短,就是遍历一条链的时间很是短)
一、异常SQL:每每意味着latch争用
大量的物理读:修改链
大量的内存读:遇到修改链的冲突
二、内存访问频繁(不停找),其实也是异常SQL形成的。
三、list太长
链上挂10000个块,被持有的概率太大……
mysql> show variables like 'i%instances'; +------------------------------+-------+
| Variable_name | Value |
+------------------------------+-------+
| innodb_buffer_pool_instances | 1 |
+------------------------------+-------+
1 row in set (0.00 sec)
因此,有时候会增长instance的数量,把大pool切成小的pool,让list链变的短一些。
一、对于MySQL 5.7
mysql> show engine innodb status\G …… SEMAPHORES ---------- OS WAIT ARRAY INFO: reservation count 23 OS WAIT ARRAY INFO: signal count 14 RW-shared spins 0, rounds 73, OS waits 5 RW-excl spins 0, rounds 1114, OS waits 5 RW-sx spins 0, rounds 0, OS waits 0 Spin rounds per wait: 73.00 RW-shared, 1114.00 RW-excl, 0.00 RW-sx
rounds:表示spin一次空转多少圈,也就是返回来询问的次数
OS waits:表示sleep,当忽然增加比较快时,说明latch争用比较严重
一、若是OS waits值比较高,说明出现latch争用,异常SQL
二、获取latch的代价:73.00 RW-shared, 1114.00 RW-excl
二、对于MySQL 5.6
mysql> show engine innodb status\G …… SEMAPHORES ---------- OS WAIT ARRAY INFO: reservation count 29758 OS WAIT ARRAY INFO: signal count 29148 Mutex spin waits 1054508, rounds 427812, OS waits 2104 RW-shared spins 26703, rounds 800527, OS waits 26673 RW-excl spins 68, rounds 27115, OS waits 888 Spin rounds per wait: 0.41 mutex, 29.98 RW-shared, 398.75 RW-excl
Mutex spin waits:能够理解成misses,空转cpu
Mutex是互斥锁、RW-shared是共享锁、RW-excl是排它锁
mysql> show engine innodb mutex; +--------+-----------------------------+----------+
| Type | Name | Status |
+--------+-----------------------------+----------+
| InnoDB | rwlock: dict0dict.cc:2687 | waits=1 |
| InnoDB | rwlock: dict0dict.cc:1184 | waits=13 |
| InnoDB | rwlock: log0log.cc:844 | waits=35 |
| InnoDB | sum rwlock: buf0buf.cc:1457 | waits=4 |
+--------+-----------------------------+----------+
4 rows in set (0.16 sec)
利用show engine innodb mutex;来解决latch和mutex问题。
[root@localhost ~]# find / -name dict0dict.cc
/usr/src/debug/percona-xtrabackup-2.4.4/storage/innobase/dict/dict0dict.cc
/usr/local/src/mysql-5.7.14/storage/innobase/dict/dict0dict.cc [root@localhost ~]# cat /usr/local/src/mysql-5.7.14/storage/innobase/dict/dict0dict.cc #查看源码信息,看其latch争用类型具体描述
一、优化SQL,下降对内存读的数量,效果比较明显。
二、增长innodb_buffer_pool_instances的数量。对于具备大内存的64位系统,能够将缓冲池拆分红多个实例(默认8个),把须要缓冲的数据hash到不一样的缓冲池中,这样能够并行的内存读写,以最大限度地减小并发操做中内存结构的争用。