2019-07-28 InnoDB鎖和索引送浊?索引和執(zhí)行計(jì)劃?

select ... for share 可在多個事務(wù)中讀丘跌, 但是不可被其他事務(wù)寫
select ... for update

https://www.hollischuang.com/archives/1716

https://www.cnblogs.com/ktgu/p/3529143.html

死鎖: 鎖被一個客戶端長期占據(jù)袭景, 一直處于鎖定狀態(tài); 對方持有對方的鎖闭树,進(jìn)入僵持狀態(tài)耸棒;
活鎖:是指線程1可以使用資源,但它很禮貌报辱,讓其他線程先使用資源与殃,線程2也可以使用資源,但它很紳士,也讓其他線程先使用資源幅疼。這樣你讓我米奸,我讓你,最后兩個線程都無法使用資源衣屏。
饑餓:是指如果線程T1占用了資源R躏升,線程T2又請求封鎖R,于是T2等待狼忱。T3也請求資源R膨疏,當(dāng)T1釋放了R上的封鎖后,系統(tǒng)首先批準(zhǔn)了T3的請求钻弄,T2仍然等待佃却。然后T4又請求封鎖R,當(dāng)T3釋放了R上的封鎖之后窘俺,系統(tǒng)又批準(zhǔn)了T4的請求......饲帅,T2可能永遠(yuǎn)等待。

Innodb行級鎖都是基于索引的瘤泪?

http://www.hollischuang.com/archives/934

上面我們提到灶泵,使用select…for update會把數(shù)據(jù)給鎖住,不過我們需要注意一些鎖的級別对途,MySQL InnoDB默認(rèn)行級鎖赦邻。行級鎖都是基于索引的,如果一條SQL語句用不到索引是不會使用行級鎖的实檀,會使用表級鎖把整張表鎖住惶洲,這點(diǎn)需要注意。

Innodb鎖

  1. InnoDB鎖和索引的關(guān)系膳犹?
  2. 執(zhí)行計(jì)劃對select ... for update 行級鎖的影響恬吕?
  3. InnoDB事務(wù)和鎖的持有?
  4. select ... for update 有什么問題须床?

文檔中的 index records 是啥铐料?

14.6.2.2 The Physical Structure of an InnoDB Index

Index records are stored in the leaf pages of their B-tree data structure.

1. InnoDB鎖和索引的關(guān)系?

14.7.3 Locks Set by Different SQL Statements in InnoDB

If you have no indexes suitable for your statement and MySQL must scan the entire table to process the statement, every row of the table becomes locked, which in turn blocks all inserts by other users to the table. It is important to create good indexes so that your queries do not unnecessarily scan many rows.
如果沒有匹配的索引則掃描全表豺旬,并且把所有行都鎖定余赢。
因此必須要創(chuàng)建必須的索引, 否則全表掃描哈垢, 所有行都被鎖定。

A locking read, an UPDATE, or a DELETE generally set record locks on every index record that is scanned in the processing of the SQL statement. It does not matter whether there are WHERE conditions in the statement that would exclude the row. InnoDB does not remember the exact WHEREcondition, but only knows which index ranges were scanned.
locking read扛拨, UPDATE, DELETE 設(shè)置 record locks在所有被掃描的索引記錄上耘分。
InnoDB不會記得確切的where條件匣椰, 僅記得被掃描的索引范圍驮俗。
如果不用索引, 所有被掃描的行都被鎖上。
用了索引飒泻,所有被掃描的索引記錄也都是鎖上。
只要被掃描桑驱,都會被鎖上将塑。
因?yàn)橛兴饕钥梢灾苯佣ㄎ唬?而不用全表掃描卜朗, 只需要掃描相關(guān)的索引記錄就行了(可能會掃描多行拔第,鎖定多行)。如果是唯一性索引场钉,則只需要掃描一行就行了蚊俺。
因?yàn)闆]有索引, 必須要全表掃描逛万, 所以表中所有行都被鎖定泳猬。

索引文件和記錄文件,兩份文件宇植, 分開存儲

index-record locks 鎖定的是索引文件中行
InnoDB所有表中如果不設(shè)置索引得封,或主鍵索引,則clustered index作為默認(rèn)索引指郁。

1. InnoDB鎖和索引的關(guān)系忙上?舉例子

mysql> show create table t ;
+-------+------------------------------------------------------------------------------------+
| Table | Create Table                                                                       |
+-------+------------------------------------------------------------------------------------+
| t     | CREATE TABLE `t` (
  `i` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

insert
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> 
mysql> 
mysql> select * from t;
+------+
| i    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    5 |
|    5 |
|    5 |
|    5 |
+------+
9 rows in set (0.00 sec)

mysql> insert into t(i) values(7);
Query OK, 1 row affected (0.00 sec)

mysql> SHOW ENGINE INNODB STATUS\G

------------
TRANSACTIONS
------------
Trx id counter 152491
Purge done for trx's n:o < 152490 undo n:o < 0 state: running but idle
History list length 5
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 281479467061704, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 281479467059896, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 281479467058992, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 152490, ACTIVE 5 sec
1 lock struct(s), heap size 1136, 0 row lock(s), undo log entries 1
MySQL thread id 24, OS thread handle 123145358168064, query id 3204 localhost root starting
SHOW ENGINE INNODB STATUS

mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

update

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> 
mysql> 
mysql> select * from t;
+------+
| i    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    5 |
|    5 |
|    5 |
|    5 |
+------+
9 rows in set (0.00 sec)

mysql> update t set i=10 where i=8;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0



mysql> SHOW ENGINE INNODB STATUS\G

------------
TRANSACTIONS
------------
Trx id counter 152491
Purge done for trx's n:o < 152490 undo n:o < 0 state: running but idle
History list length 5
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 281479467061704, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 281479467059896, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 281479467058992, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 152490, ACTIVE 97 sec
3 lock struct(s), heap size 1136, 12 row lock(s), undo log entries 1
MySQL thread id 24, OS thread handle 123145358168064, query id 3206 localhost root starting
SHOW ENGINE INNODB STATUS

mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

delete



mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t;
+------+
| i    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    5 |
|    5 |
|    5 |
|    5 |
+------+
9 rows in set (0.00 sec)


mysql> delete from t where i=9;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW ENGINE INNODB STATUS\G

------------
TRANSACTIONS
------------
Trx id counter 152491
Purge done for trx's n:o < 152490 undo n:o < 0 state: running but idle
History list length 5
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 281479467061704, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 281479467059896, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 281479467058992, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 152490, ACTIVE 158 sec
3 lock struct(s), heap size 1136, 12 row lock(s), undo log entries 1
MySQL thread id 24, OS thread handle 123145358168064, query id 3208 localhost root starting
SHOW ENGINE INNODB STATUS

mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

總結(jié): 驗(yàn)證了 repeatable-read isolation level下的設(shè)置的鎖

locking read:
select ... for update
select ... lock in share mode
UPDATE
INSERT

InnoDB不會記得確切的where條件, 僅記得被掃描的索引范圍坡氯。
如果不用索引晨横, 所有被掃描的行都被鎖上。
用了索引箫柳,所有被掃描的索引記錄也都是鎖上手形。
只要被掃描,都會被鎖上悯恍。
因?yàn)橛兴饕饪罚钥梢灾苯佣ㄎ唬?而不用全表掃描, 只需要掃描相關(guān)的索引記錄就行了(可能會掃描多行涮毫,鎖定多行)瞬欧。如果是唯一性索引,則只需要掃描一行就行了罢防。
因?yàn)闆]有索引艘虎, 必須要全表掃描, 所以表中所有行都被鎖定咒吐。

index-record locks 僅鎖定索引記錄(索引文件中的)
Gap locks僅鎖定間隙(索引文件中)
next-key locks:
index-record locks和Gap locks的結(jié)合野建, 同時鎖定索引記錄和索引記錄間隙属划。
如果沒有索引,則全表掃描候生, 鎖住表中所有記錄同眯。

鎖開銷

https://keithlan.github.io/2017/06/05/innodb_locks_show_engine/
鎖10條記錄和鎖1條記錄的開銷是成正比的嗎?

  1. 由于鎖的內(nèi)存對象針對的是頁而不是記錄唯鸭,所以開銷并不是非常大
  2. 鎖10條記錄和鎖1條記錄的內(nèi)存開銷都是一樣的须蜗,都是heap size=1136個字節(jié)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市目溉,隨后出現(xiàn)的幾起案子明肮,更是在濱河造成了極大的恐慌,老刑警劉巖停做,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晤愧,死亡現(xiàn)場離奇詭異,居然都是意外死亡蛉腌,警方通過查閱死者的電腦和手機(jī)官份,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烙丛,“玉大人舅巷,你說我怎么就攤上這事『友剩” “怎么了钠右?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長忘蟹。 經(jīng)常有香客問我飒房,道長,這世上最難降的妖魔是什么媚值? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任狠毯,我火速辦了婚禮,結(jié)果婚禮上褥芒,老公的妹妹穿的比我還像新娘嚼松。我一直安慰自己,他們只是感情好锰扶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布献酗。 她就那樣靜靜地躺著,像睡著了一般坷牛。 火紅的嫁衣襯著肌膚如雪罕偎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天京闰,我揣著相機(jī)與錄音颜及,去河邊找鬼痴怨。 笑死,一個胖子當(dāng)著我的面吹牛器予,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捐迫,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼乾翔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了施戴?” 一聲冷哼從身側(cè)響起反浓,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赞哗,沒想到半個月后雷则,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肪笋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年月劈,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片藤乙。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡猜揪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出坛梁,到底是詐尸還是另有隱情而姐,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布划咐,位于F島的核電站拴念,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏褐缠。R本人自食惡果不足惜政鼠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望送丰。 院中可真熱鬧缔俄,春花似錦、人聲如沸器躏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽登失。三九已至遏佣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間揽浙,已是汗流浹背状婶。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工意敛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人膛虫。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓草姻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親稍刀。 傳聞我的和親對象是個殘疾皇子撩独,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355