mysql鎖表機制分析

2021-06-25 14:50:41 字數 4273 閱讀 5368

為了給高併發情況下的

mysql

進行更好的優化,有必要了解一下mysql查詢更新時的鎖表機制。

一、概述

mysql有三種鎖的級別:頁級、表級、行級。

myisam和memory儲存引擎採用的是表級鎖(table-level locking);bdb儲存引擎採用的是頁面鎖(page-level

locking),但也支援表級鎖;innodb儲存引擎既支援行級鎖(row-level locking),也支援表級鎖,但預設情況下是採用行級鎖。

mysql這3種鎖的特性可大致歸納如下:

表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的概率最高,併發度最低。

行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。

頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般。

二、myisam表鎖

myisam儲存引擎只支援表鎖,是現在用得最多的儲存引擎。

1、查詢表級鎖爭用情況

可以通過檢查table_locks_waited和table_locks_immediate狀態變數來分析

系統上的表鎖定爭奪:

mysql> show status like 『table%』;

+———————–+———-+

| variable_name | value |

+———————–+———-+

| table_locks_immediate | 76939364 |

| table_locks_waited | 305089 |

+———————–+———-+

2 rows in set (0.00 sec)table_locks_waited的值比較高,說明存在著較嚴重的表級鎖爭用情況。

2、mysql表級鎖的鎖模式

mysql的表級鎖有兩種模式:表共享讀鎖(table read lock)和表獨佔寫鎖(table write

lock)。myisam在執行查詢語句(select)前,會自動給涉及的所有表加讀鎖,在執行更新操作(update、delete、insert等)前,會自動給涉及的表加寫鎖。

所以對myisam表進行操作,會有以下情況:

a、對myisam表的讀操作(加讀鎖),不會阻塞其他程序對同一表的讀請求,但會阻塞對同一表的寫請求。只有當讀鎖釋放後,才會執行其它程序的寫操作。

b、對myisam表的寫操作(加寫鎖),會阻塞其他程序對同一表的讀和寫操作,只有當寫鎖釋放後,才會執行其它程序的讀寫操作。

下面通過例子來進行驗證以上觀點。資料表gz_phone裡有二百多萬資料,欄位id,phone,ua,day。現在同時用多個客戶端同時對該錶進行操作分析。

a、當我用客戶端1進行乙個比較長時間的讀操作時,分別用客戶端2進行讀和寫操作:

client1:

mysql>select count(*) from gz_phone group by ua;

75508 rows in set (3 min 15.87 sec) client2:

select id,phone from gz_phone limit 1000,10;

+——+——-+

| id | phone |

+——+——-+

| 1001 | 2222 |

| 1002 | 2222 |

| 1003 | 2222 |

| 1004 | 2222 |

| 1005 | 2222 |

| 1006 | 2222 |

| 1007 | 2222 |

| 1008 | 2222 |

| 1009 | 2222 |

| 1010 | 2222 |

+——+——-+

10 rows in set (0.01 sec)

mysql> update gz_phone set phone=』11111111111′where id=1001;

query ok, 0 rows affected (2 min 57.88 sec)

rows matched: 1 changed: 0 warnings: 0

說明當資料表有乙個讀鎖時,其它程序的查詢操作可以馬上執行,但更新操作需等待讀鎖釋放後才會執行。

b、當用客戶端1進行乙個較長時間的更新操作時,用客戶端2,3分別進行讀寫操作:

client1:

mysql> update gz_phone set phone=』11111111111′;

query ok, 1671823 rows affected (3 min 4.03 sec)

rows matched: 2212070 changed: 1671823 warnings: 0 client2:

mysql> select id,phone,ua,day from gz_phone limit 10;

+—-+——-+——————-+————+

| id | phone | ua | day |

+—-+——-+——————-+————+

| 1 | 2222 | sonyericssonk310c | 2007-12-19 |

| 2 | 2222 | sonyericssonk750c | 2007-12-19 |

| 3 | 2222 | maui wap browser | 2007-12-19 |

| 4 | 2222 | nokia3108 | 2007-12-19 |

| 5 | 2222 | lenovo-i750 | 2007-12-19 |

| 6 | 2222 | bird_d636 | 2007-12-19 |

| 7 | 2222 | sonyericssons500c | 2007-12-19 |

| 8 | 2222 | samsung-sgh-e258 | 2007-12-19 |

| 9 | 2222 | nokian73-1 | 2007-12-19 |

| 10 | 2222 | nokia2610 | 2007-12-19 |

+—-+——-+——————-+————+

10 rows in set (2 min 58.56 sec) client3:

mysql> update gz_phone set phone=』55555′where id=1;

query ok, 1 row affected (3 min 50.16 sec)

rows matched: 1 changed: 1 warnings: 0

說明當資料表有乙個寫鎖時,其它程序的讀寫操作都需等待讀鎖釋放後才會執行。

3、併發插入

原則上資料表有乙個讀鎖時,其它程序無法對此表進行更新操作,但在一定條件下,myisam表也支援查詢和插入操作的併發進行。

myisam儲存引擎有乙個系統變數concurrent_insert,專門用以控制其併發插入的行為,其值分別可以為0、1或2。

a、當concurrent_insert設定為0時,不允許併發插入。

b、當concurrent_insert設定為1時,如果myisam表中沒有空洞(即表的中間沒有被刪除的行),myisam允許在乙個程序讀表的同時,另乙個程序從表尾插入記錄。這也是mysql的預設設定。

c、當concurrent_insert設定為2時,無論myisam表中有沒有空洞,都允許在表尾併發插入記錄。

4、myisam的鎖排程

由於mysql認為寫請求一般比讀請求要重要,所以如果有讀寫請求同時進行的話,mysql將會優先執行寫操作。這樣myisam表在進行大量的更新操作時(特別是更新的字段中存在索引的情況下),會造成查詢操作很難獲得讀鎖,從而導致查詢阻塞。

我們可以通過一些設定來調節myisam的排程行為:

a、通過指定啟動引數low-priority-updates,使myisam引擎預設給予讀請求以優先的權利。

b、通過執行命令set low_priority_updates=1,使該連線發出的更新請求優先順序降低。

c、通過指定insert、update、delete語句的low_priority屬性,降低該語句的優先順序。

上面3種方法都是要麼更新優先,要麼查詢優先的方法。這裡要說明的就是,不要盲目的給mysql設定為讀優先,因為一些需要長時間執行的查詢操作,也會使寫程序「餓死」。只有根據你的實際情況,來決定設定哪種操作優先。這些方法還是沒有從根本上同時解決查詢和更新的問題。

在乙個有大資料量高並發表的mysql裡,我們還可採用另一種策略來進行優化,那就是通過mysql主從(讀寫)分離來實現負載均衡,這樣可避免優先哪一種操作從而可能導致另一種操作的堵塞。下面將用乙個篇幅來說明mysql的讀寫分離技術

mysql 鎖表機制分析

412 views posted in 2010年08月30日 10 00h.scofield 為了給高併發情況下的mysql進行更好的優化,有必要了解一下mysql查詢更新時的鎖表機制。一 概述 mysql有三種鎖的級別 頁級 表級 行級。myisam和memory儲存引擎採用的是表級鎖 tabl...

mysql 鎖表機制分析

為了給高併發情況下的mysql進行更好的優化,有必要了解一下mysql查詢更新時的鎖表機制。一 概述 mysql有三種鎖的級別 頁級 表級 行級。myisam和memory儲存引擎採用的是表級鎖 table level locking bdb儲存引擎採用的是頁面鎖 page level lockin...

mysql鎖表機制分析

mysql有三種鎖的級別 頁級 表級 行級。myisam和memory儲存引擎採用的是表級鎖 table level locking bdb儲存引擎採用的是頁面鎖 page level locking 但也支援表級鎖 innodb儲存引擎既支援行級鎖 row level locking 也支援表級鎖...