表級鎖的mysql讀寫 Mysql的表級鎖

2021-10-19 06:41:42 字數 3412 閱讀 6881

我們首先需要知道的乙個大前提是:mysql的鎖是由具體的儲存引擎實現的。所以像mysql的預設引擎myisam和第三方外掛程式引擎 innodb的鎖實現機制是有區別的。可根據不同的場景選用不同的鎖定機制。

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

一、定義

每次鎖定的是一張表的鎖機制就是表級別鎖定(table-level)。它是mysql各儲存引擎中粒度最大的鎖定機制。

二、優缺點

1. 優點

實現邏輯簡單,開銷小。

獲取鎖和釋放鎖的速度快。

由於表級鎖一次會將整個表鎖定,所以能很好的避免死鎖問題。

2. 缺點

由於鎖粒度最大,因此出現爭用被鎖定資源的概率也會最高,致使併發度十分低下。

三、支援儲存引擎

使用表級鎖定的主要有myisam,memory,csv等一些非事務性儲存引擎。

四、表級鎖型別

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

鎖模式的相容性:

對myisam表的讀操作,不會阻塞其他使用者對同一表的讀請求,但會阻塞對同一表的寫操作;

對myisam表的寫操作,則會阻塞其他使用者對同一表的讀和寫操作;

myisam表的讀操作與寫操作之間,以及寫操作之間是序列的。當乙個執行緒獲得對乙個表的寫鎖後,只有持有鎖的執行緒可以對錶進行更新操作。其他執行緒的讀、寫操作都會等待,直到鎖被釋放為止。

五、如何加表鎖

在執行查詢語句(select)前,會自動給涉及的所有表加讀鎖

在執行更新操作(update、delete、insert等)前,會自動給涉及的表加寫鎖。這個過程並不需要使用者干預,因此不需要直接用lock table命令給myisam表顯式加鎖。

顯示加寫鎖:

// 當乙個執行緒獲得對乙個表的寫鎖後,只有持有鎖的執行緒可以對錶進行更新操作。

// 其他執行緒的讀、寫操作都會等待,直到鎖被釋放為止。

// test表將會被鎖住,另乙個執行緒執行select * from test where id = 3;將會一直等待,直到test表解鎖

lock table test write;

顯示加讀鎖

// test表將會被鎖住,另乙個執行緒執行select * from test where id = 3;不會等待

// 執行update test set name='peter' where id = 4;將會一直等侍,直到test表解鎖

lock table test read;

顯示釋放鎖:

unlock tables;

需要注意的是,在同乙個sql session裡,如果已經獲取了乙個表的鎖定,則對沒有鎖的表不能進行任何操作,否則會報錯。

// 鎖定test表

lock table test write;

// 操作鎖定表沒問題

select * from test where id = 4;

// 操作沒有鎖的表會報錯

select * from bas_farm where id =1356

報錯:[err] 1100 - table 'bas_farm' was not locked with lock tables。這是因為myisam希望一次獲得sql語句所需要的全部鎖。這也正是myisam表不會出現死鎖的原因。

當然,你也不必擔心,myisam引擎的預設方式是會給同乙個session裡的所有表都加上鎖的,不會麻煩你自己顯示操作的。

六、檢視表級鎖爭用情況

執行:show status like 『table%』;

mysql> show status like 'table%';

| variable_name | value |

| table_locks_immediate | 20708 |

| table_locks_waited | 0 |

table_locks_immediate:產生表級鎖定的次數;

table_locks_waited:出現表級鎖定爭用而發生等待的次數;

如果table_locks_waited狀態值比較高,那麼說明系統中表級鎖定爭用現象比較嚴重,就需要進一步分析為什麼會有較多的鎖定資源爭用了。

七、優化表級鎖定

優化表級鎖時的最大問題是:提高併發度

###1. 通過減少查詢時間縮短鎖定時間

縮短鎖定時間的總體原則是:讓query執行時間盡可能的短。

儘量減少大的、複雜的query,將複雜query分拆成幾個小的query分步執行;

盡可能的建立足夠高效的索引,讓資料檢索更迅速;

盡量讓myisam儲存引擎的表只存放必要的資訊,控制字段型別;

利用合適的機會優化myisam表資料檔案。

###2. 設定可併發插入:concurrent_insert=2

myisam的表鎖雖是讀寫互相阻塞的,但依然能夠實現並行操作。myisam儲存引擎有乙個控制是否開啟concurrent insert(併發插入)功能的引數選項:concurrent_insert,取值範圍為0,1,2。

concurrent_insert=0,不允許併發插入。

concurrent_insert=1,如果myisam表中沒有空洞(即表的中間沒有被刪除的行),myisam允許在乙個執行緒讀表的同時,另乙個執行緒從表尾插入記錄。這是mysql的預設設定;

concurrent_insert=2,無論myisam表中有沒有空洞,都允許在表尾併發插入記錄;

所以,我們可通過設定concurrent_insert=2,同時定期在系統空閒時段執行optimize table tablename語句來整理空間碎片,收回因刪除記錄而沒有真正釋放的空間,從而提高併發。optimize參考:mysql中optimize table的作用及使用

###3. 合理設定讀寫優先順序

myisam儲存引擎預設是寫優先順序大於讀優先順序。即使是寫請求後到,寫鎖也會插到讀鎖請求之前。

update low_priority article set click_num=134 where id = 823

low_priority使得系統認為update操作優化級比讀操作低,如果同時出現讀操作和上面的更新操作,則優先執行讀操作。

mysql提供了幾個語句調節符,允許你修改它的排程策略:

low_priority關鍵字應用於:delete、insert、load data、replace和update。

high_priority關鍵字應用於:select、insert語句。

delayed(延遲)關鍵字應用於:insert、replace語句。

如果你希望所有支援low_priority選項的語句都預設地按照低優先順序來處理,那麼可能使用**low-priority-updates**選項來啟動伺服器。然後可通過使用insert high_priority table.....來把個別我們希望的insert語句提高到正常的寫入優先順序。

MySQL行級鎖 表級鎖

行級鎖 表級鎖的資料不能被其它事務再鎖定,也不被其它事務修改 修改 刪除 是表級鎖時,不管是否查詢到記錄,都會鎖定表 innodb 行鎖是通過給索引上的索引項加鎖 來實現的,這一點mysql與 oracle 不同,後者是通過在資料塊中對相應資料行加鎖來實現的。innodb這種行鎖實現特點意味著 只有...

mysql的行級鎖 表級鎖 頁級鎖

鎖是在執行多執行緒時用於強行限制資源訪問的同步機制,即用於在併發控制中保證對互斥要求的滿足 行級鎖 是mysql中鎖定粒度最細的一種鎖,表示只針對當前操作的行進行加鎖。行級鎖能大大減少資料庫操作的衝突。其加鎖粒度最小,但加鎖的開銷也最大。行級鎖分為共享鎖和排他鎖 特點 開銷大,加鎖慢,會出現死鎖 鎖...

mysql 讀寫鎖 表鎖myisam

讀鎖 session1 lock table book read unlock tables session1可以讀book 不可以寫book 也不可以讀寫其它表 session2可以讀book 也可以讀寫其它表 可以寫book 但阻塞的需要session1解鎖後unlock tables 寫鎖 s...