數據庫表鎖和行鎖

頁級鎖:引擎BDB。mysql

表級鎖:引擎MyISAM,鎖住整個表,能夠同時讀,寫不行。web

行級鎖:引擎InnoDB,單獨的一行記錄加鎖。sql

表級,直接鎖定整張表,在鎖按期間,其餘進程沒法對該表進行寫操做。若是你是寫鎖,則其餘進程沒法進行讀操做。數據庫

行級,僅對指定的記錄進行加鎖,這樣其餘進程仍是能夠對同一張表中其餘的記錄進行操做。多線程

頁級,表鎖速度快,但衝突多,行級鎖衝突少,但速度慢。因此取了折中的頁級,一次鎖定相鄰的一組記錄。併發

mysql5.1支持對MyISAM和MEMORY進行表級鎖定,對BDB進行頁級鎖定,對InnoDB進行行級鎖定。性能

 

對於write,mysql使用的表鎖定方法原理以下:線程

若是在表上沒有鎖,在它上面放一個寫鎖。不然,把鎖定請求放在寫鎖定隊列中。索引

對read,mysql使用的鎖定方法原理以下:隊列

若是在表上沒有寫鎖定,把一個讀鎖定放到它上面。不然,把鎖清秋放在讀鎖定隊列中。

 

InnoDB使用行鎖定,BDB使用頁鎖定。對於這兩種存儲引擎,對可能存在死鎖。這是由於在sql語句處理期間,InnoDB自動得到行鎖定和BDB得到頁鎖定,而不是在事務啓動時得到。

行鎖定的優勢:

一、當在許多線程中訪問不一樣的行時只存在少許鎖定衝突。

二、回滾時只有少許的更改。

三、能夠長時間鎖定單一的行

行級鎖定的缺點:

一、比頁級或表級鎖定佔用更多的內存。

二、當在表的大部分中使用時,比頁級或表級鎖定速度慢,由於必須獲取更多的鎖。

三、若是在大部分數據上常常進行GroupBY操做或者必須常常掃描整個表,比其餘鎖定明顯慢不少。

四、用高級別鎖定,經過支持不一樣的類型鎖定,也能夠很容易調節應用程序,由於其鎖成本小於行級鎖定。

在如下狀況,表鎖定優先頁級或行級鎖定:

一、表的大部分語句用於讀取。

二、對嚴格的關鍵字進行讀取和更新,能夠用單一的讀取關鍵詞來提取一行。

三、select結合並行的insert語句,而且只有不多的update或delete語句。

四、在整個表上有許多掃描或groupby操做,沒有任何寫操做。

===============mysql鎖表類型和解鎖語句========================

若是想要在一個表上作大量的insert和select操做,可是並行的插入卻不可能時,能夠江櫸路插入到臨時表中,而後按期將臨時表中的數據更新到實際的表裏。命令:

mysql>LOCK TABLE real_table WRITE,insert_table WRITE;

mysql>INSERT INTO real_table select * from insert_table;

mysql>TRUNCATE TABLE insert_table;

mysql>UNLOCK TABLES;

行級鎖的優勢:

一、在不少線程請求不一樣記錄時減小衝突鎖。

二、事務回滾時減小改變數據。

三、使長時間對單獨的一行記錄加鎖成爲可能。

行級鎖的缺點:比頁級鎖和表級鎖小號更多的內存。

鎖是計算機協調多個進程或線程併發訪問某一資源的機制,不一樣的數據庫的鎖機制大同小異。因爲數據庫資源是一種供不少用戶共享的資源,因此如何保證數據併發訪問的一致性、有效性是全部數據庫必須解決的一個問題,鎖衝突也是影響數據庫併發訪問性能的重要因素。瞭解鎖機制不只可使咱們更有效的開發利用數據庫資源,也使咱們可以更好地維護數據庫,從而提升數據庫的性能。

mysql的鎖機制比較簡單,其顯著的特色是不一樣的存儲引擎支持不一樣的鎖機制。

例如:MyISAM和MEMORY存儲引擎採用的是表級鎖;BDB存儲引擎採用的是頁面鎖,同時也支持表級鎖;InnoDB存儲引擎即支持行級鎖,也支持表級鎖,默認是採用行級鎖。

以上三種鎖的特性可大體概括以下:

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

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

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

三種鎖各有特色,若僅從鎖的角度來講,表級鎖更適合以查詢爲主,只有少許按索引條件更新數據的應用,如web應用;行級鎖更適合於大量按索引條件併發更新少許不一樣數據,同時又有併發查詢的應用,如一些在線事務處理系統。

mysql表級鎖有兩種模式:表共享讀鎖和表獨佔寫鎖。就是說對MyISAM表進行讀操做時,他不會阻塞其餘用戶對同一張表的讀請求,但會阻塞對同一表的寫操做;而對MyISAM表的寫操做,則會阻塞其餘用戶對同一張表的讀和寫操做。

MyISAM表的讀和寫是串行的,即在進行讀操做時不能進行寫操做,反之也是同樣。但在必定條件下MyISAM表也支持查詢和插入的操做的併發進行,其機制是經過一個系統變量來進行,當其值設置爲0時,不容許併發插入;其值爲1時,若是MyISAM表中沒有空洞(即表中沒有被刪除的行),MyISAM容許在一個進程讀表的同時,另外一個進程從表尾插入記錄;當其值爲2時,不管MyISAM表中有木有空洞,都容許在表尾併發插入記錄。

MyISAM鎖調度實現:當一個線程請求對MyISAM表中的讀鎖,同時另外一個線程也請求同一張表的寫鎖,此時寫進程優先得到鎖。可是大量的寫操做會形成查詢操做很難得到讀鎖,從而造程永久阻塞。能夠經過指定參數low-priority-updates,使MyISAM默認引擎給與讀請求優先的權利,設置爲1(set low-priority-updates=1),使優先級下降。

InnoDB鎖與MyISAM鎖的最大不一樣在於:一時支持事務。二是採用了行級鎖。

事務四個屬性(ACID):

一、原子性:事務是一個原子操做單位,其對數據的修改,要麼所有執行,要麼所有不執行。

二、一致性:在事務開始和完成時,數據都必須保持一致狀態。

三、隔離性:數據庫系統提供必定的隔離機制,保證事務在不受外部併發操做影響的獨立環境執行。

四、持久性:事務完成後,他對於數據的修改是永久性的。

InnoDB有兩種模式的行鎖:

1)共享鎖:容許一個事務去讀一行,阻止其餘事務得到相同數據集的排他鎖。

select * from table_name where ... lock in share mode

2)排他鎖:容許得到排它鎖的事務更新數據,阻止其餘事物取得相同數據集的共享讀鎖和排他寫鎖。

select * from table_name where ... for update

爲了容許行鎖和表鎖共存,實現多粒度鎖機制;同時還有兩種內部使用的意向鎖(都是表鎖),分別爲意向共享和意向排它鎖。

InnoDB行鎖是經過給索引加鎖來實現的,即只有經過索引條件檢索數據,InnoDB才使用行級鎖,不然將使用表鎖。

==================mysqlInnoDB鎖表與鎖行===============

因爲InnoDB預設是Row-Level Lock,因此只有明確的指定主鍵,mysql纔會執行row local(只鎖住被選取的資料例),不然mysql將會執行table lock(鎖表)。

例:明確指定主鍵 row lock

select * from table_name where id=3 for update

例:明確指定主鍵,若查無資源,無lock

select* from table_name where id=4 for update

例:無主鍵,table lock 

select * from table_name where name=「li」 for update

例:主鍵不明確,table lock

select * from table_name where id <>5 for update

例:主鍵不明確,table lock 

select * from table_name where id like ‘3’ for update

MyISAM只支持表鎖,InnoDB支持行級鎖。

相關文章
相關標籤/搜索