鎖的介紹

Ⅰ、鎖的概念

1.1 鎖的做用

  • 對共享資源進行併發訪問
  • 提供數據的完整性和一致性

1.2 鎖的實現

每一個數據庫的鎖的實現徹底不一樣數據庫

  • MyISAM表鎖
  • InnoDB行級鎖
    Like Oracle???不同
  • Microsoft SQL Server 行級鎖with鎖升級
    行鎖超過5000個就升級爲行級鎖或者表鎖

MySQL作的很棒,可是很難理解。session

1.3 latch(閂鎖)

  • mutex 互斥鎖
  • rw-lock

他們是鎖嗎?數據結構

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這時候就會等待了
相關文章
相關標籤/搜索