每一個數據庫的鎖的實現徹底不一樣數據庫
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這時候就會等待了