每一个数据库的锁的实现彻底不一样数据库
MySQL作的很棒,可是很难理解。session
他们是锁吗?数据结构
latch在内存中,控制内存数据结构的并发访问,针对程序内部资源(好比:全局变量),锁的是并发资源(临界区),lock是数据库层的锁,针对的是事务,锁的对象不是内存结构而是行并发
数据库中发生死锁会选择一个事务回滚,程序层中没有死锁检测mvc
latch无处不在,对某一个对象并发访问的控制,和lock也没啥比如较的,彻底不搭界日志
lock由latch来保证和实现code
tips:
如何查看latch? 了解便可,基本用不着对象
(root@localhost) [(none)]> show engine innodb mutex; +--------+---------------------------+----------+ | Type | Name | Status | +--------+---------------------------+----------+ | InnoDB | rwlock: dict0dict.cc:1184 | waits=3 | | InnoDB | rwlock: log0log.cc:838 | waits=23 | +--------+---------------------------+----------+ 2 rows in set (0.00 sec)
即便很大也没什么意义,表明不了什么,waits很长就表明这个latch有并发
某时间点数据写入量很大,那重作日志的这把latch可能就会很大
读取量大的话,bp的latch可能会很大blog
session1: (root@localhost) [test]> show create table l\G *************************** 1. row *************************** Table: l Create Table: CREATE TABLE `l` ( `a` int(11) NOT NULL, `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, `d` int(11) DEFAULT NULL, PRIMARY KEY (`a`), UNIQUE KEY `c` (`c`), KEY `b` (`b`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 1 row in set (0.00 sec) (root@localhost) [test]> select * from l; +---+------+------+------+ | a | b | c | d | +---+------+------+------+ | 2 | 4 | 6 | 8 | | 4 | 6 | 8 | 10 | | 6 | 8 | 10 | 12 | | 8 | 10 | 12 | 14 | +---+------+------+------+ 4 rows in set (0.00 sec) (root@localhost) [test]> begin; Query OK, 0 rows affected (0.00 sec) (root@localhost) [test]> delete from l where a = 2; Query OK, 1 row affected (0.00 sec) (root@localhost) [test]> update l set b = b + 1 where a = 4; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 (root@localhost) [test]> select * from l; +---+------+------+------+ | a | b | c | d | +---+------+------+------+ | 4 | 7 | 8 | 10 | | 6 | 8 | 10 | 12 | | 8 | 10 | 12 | 14 | +---+------+------+------+ 3 rows in set (0.00 sec) 此时这两条记录上就被加了排他锁,在当前session看到这两条记录已经变化了
再开一个session看到的仍是原来的记录,由于事务还没提交,mvcc特性事务
session2: (root@localhost) [test]> select * from l; +---+------+------+------+ | a | b | c | d | +---+------+------+------+ | 2 | 4 | 6 | 8 | | 4 | 6 | 8 | 10 | | 6 | 8 | 10 | 12 | | 8 | 10 | 12 | 14 | +---+------+------+------+ 4 rows in set (0.00 sec) (root@localhost) [test]> show engine innodb status\G ... LIST OF TRANSACTIONS FOR EACH SESSION: ---TRANSACTION 29474225, ACTIVE 46 sec 2 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 2 MySQL thread id 296696, OS thread handle 140076853794560, query id 34555618 localhost root Trx read view will not see trx with id >= 29474796, sees < 29474796 ... 一般认为增删改会加排它锁,其实select也能够加,select后面用一个for update就对这条记录加锁了,可是这个锁住了没事,新开session依然能够读,mvcc机制————默认读永远不会被锁,即便你在全表更新 但新开session去select也加for update这时候就会等待了