四、innodb鎖機制
1、表鎖:
意向共享鎖(intention shared lock, is):表級意向共享鎖,即表示事務有意向對錶中的某些行加共享s鎖。如select ... lock in share mode語句,在加行鎖之前會在表上現加is鎖,這樣可以提高鎖衝突檢測的效率,同時也可以避免事務在表級新增會使其他事務行鎖失效的表級鎖。
加鎖sql:select ... lock in share mode;
意向排它鎖(intention exclusive lock, ix):表級意向獨佔鎖,即表示事務有意向對錶中的某些行加排它x鎖。一般來說delete、update語句和select ... for update語句都會在加行鎖之前先加表級ix鎖,除非未用到索引(此時直接加表級x鎖)
加鎖sql: select ... for update;
2、innodb行鎖:
(1)、共享鎖(share locks,記為s鎖):即lock tables ... read新增的s鎖。若事務t對資料物件a加上s鎖,則事務t可以讀a但不能修改a,其他事務只能再對a加s鎖,而不能加x鎖,直到t釋放a上的s鎖。這保證了其他事務可以讀a,但在t釋放a上的s鎖之前不能對a做任何修改。
(2)、排他鎖(exclusive locks,記為x鎖) :即lock tables ... write新增的x鎖。若事務t對資料物件a加上x鎖,事務t可以讀a也可以修改a,其他事務不能再對a加任何鎖,直到t釋放a上的鎖。mysql innodb引擎預設的修改資料語句:update,delete,insert都會自動給涉及到的資料加上排他鎖,select語句預設不會加任何鎖型別,如果加排他鎖可以使用select …for update語句,加共享鎖可以使用select … lock in share mode語句。所以加過排他鎖的資料行在其他事務中是不能修改資料的,也不能通過for update和lock in share mode鎖的方式查詢資料,但可以直接通過select …from…查詢資料,因為普通查詢沒有任何鎖機制。
(3)、記錄鎖(record locks):分為s和x兩種模式。一定是加在索引記錄上的,即便是乙個沒有定義任何索引的表,innodb也會建立乙個隱式的聚集索引,在用到此索引時加record lock。
加鎖sql:select * from table where id=1 for update;
(4)、間隙鎖(gap locks):用於鎖定2個索引記錄之間、或第乙個索引記錄之前、或最後乙個索引記錄之後的範圍。gap lock主要是為了解決幻讀問題。
加鎖sql:select * from table where id between 8 and 15 for update;
(5)、臨鍵鎖(next-key locks):即record lock和gap lock的合體。封鎖範圍,既包含索引記錄,又包含索引區間。
(6)、插入意向鎖(insert intention locks):是間隙鎖(gap locks)的一種(所以,也是實施在索引上的),它是專門針對insert操作的。多個事務,在同乙個索引,同乙個範圍區間插入記錄時,如果插入的位置不衝突,不會阻塞彼此。只要不是插入相同的index record,多個事務向同乙個gap插入記錄是不會阻塞的。insert語句的基本加鎖模式為:表級ix鎖--行級插入意向鎖--行級鎖。
(7)、自增鎖(auto-inc locks):自增鎖是一種特殊的表級別鎖(table-level lock),專門針對事務插入auto_increment型別的列。最簡單的情況,如果乙個事務正在往表中插入記錄,所有其他事務的插入必須等待,以便第乙個事務插入的行,是連續的主鍵值。
注意:
innodb行鎖是通過給索引上的索引項加鎖來實現的,這一點mysql與oracle不同,後者是通過在資料塊中對相應資料行加鎖來實現的。innodb這種行鎖實現特點意味著:只有通過索引條件檢索資料,innodb才使用行級鎖,否則,innodb將使用表鎖!
排它鎖是很強的鎖,不與其他型別的鎖相容。修改和刪除某一行的時候,必須獲得強鎖,禁止這一行上的其他併發,以保障資料的一致性。xs
ixisx衝突
衝突衝突衝突s
衝突相容
衝突相容
ix衝突
衝突相容
相容is
衝突相容
相容相容
3、mvcc機制(多版本併發控制)
在mysql中,myisam使用的是表鎖,innodb使用的是行鎖。而innodb的事務分為四個隔離級別,其中預設的隔離級別repeatable read需要兩個不同的事務相互之間不能影響,而且還能支援併發,這點悲觀鎖是達不到的,所以repeatable read採用的就是樂觀鎖,而樂觀鎖的實現採用的就是mvcc。正是因為有了mvcc,才造就了innodb強大的事務處理能力。mvcc解決的問題是讀寫互相不阻塞的問題,每次更新都產生乙個新的版本,讀的話可以讀歷史版本。乙個讀寫事務在執行的過程中在訪問資料之前先加讀/寫鎖這種實現叫做悲觀鎖,悲觀體現在,先加鎖,獨佔資料,防止別人加鎖。樂觀鎖是讀寫事務在真正提交之前,不加讀/寫鎖,而是先看一下資料的版本/時間戳,等到真正提交的時候再看一下版本/時間戳,如果兩次相同,說明別人期間沒有對資料進行過修改,那麼就可以放心提交。樂觀體現在,訪問資料時不提前加鎖。在資源衝突不激烈的場合,用樂觀鎖效能較好。但是,如果資源衝突嚴重,樂觀鎖的實現會導致事務提交的時候經常看到別人在他之前已經修改了資料,然後要進行回滾或者重試,還不如一上來就加鎖。所以通常我們把沒有開啟mvcc特性的,使用原來的鎖機制來保證資料一致性的這種鎖叫悲觀鎖,而對開啟mvcc機制的鎖,叫做樂觀鎖。mvcc是通過儲存資料在某個時間點的快照來實現的,不同儲存引擎的mvcc實現是不同的,典型的有樂觀併發控制和悲觀併發控制。
(1)、操作過程:mvcc是在每一行記錄的後面增加兩個隱藏列,記錄建立版本號和刪除版本號,該版本號使用的就是事務版本號,而每乙個事務在啟動的時候,都有乙個唯一的遞增的版本號。
①、在插入操作時,記錄的建立版本號就是事務版本號。
例:當前事務版本號為2執行sql:insert table values(1,'test');
idname
create version
delete version
test
②、在更新操作時,採用的是先標記舊的那行記錄為已刪除,並且刪除版本號更新為當前事務版本號,然後插入一行新的記錄。
例:當前事務版本號為3執行sql:update table set name = 'new_test' where id = 1;
idname
create version
delete version
test
new_test
③、在刪除操作時,就把事務版本號作為刪除版本號。
例:當前事務版本號為4執行sql:delete from table where id=1;
idname
create version
delete version
test
new_test
4、mvcc和occ區別
(1)、多版本併發控制(mvcc)是一種用來解決讀-寫衝突的無鎖併發控制,也就是為事務分配單向增長的時間戳,為每個修改儲存乙個版本,版本與事務時間戳關聯,讀操作唯讀該事務開始前的資料庫的快照。 這樣在讀操作不用阻塞寫操作,寫操作不用阻塞讀操作的同時,避免了髒讀和不可重複讀。
(2)、樂觀併發控制(occ)是一種用來解決寫-寫衝突的無鎖併發控制,認為事務間爭用沒有那麼多,所以先進行修改,在提交事務前,檢查一下事務開始後,有沒有新提交改變,如果沒有就提交,如果有就放棄並重試。樂觀併發控制類似自選鎖。樂觀併發控制適用於低資料爭用,寫衝突比較少的環境。
5、死鎖查詢以及解決
鎖表測試語句:
lock tables cpoe_advice_fees read ;
select sleep(160) ;
unlock tables cpoe_advice_fees ;
(1)、查詢死鎖程序,然後殺死該程序
①、-- 檢視是否鎖表,in_use:表當前被查詢使用的次數。如果該數為零,則表是開啟的,但是當前沒有被使用。
show open tables where in_use > 0 ;
②、-- 查詢程序
show processlist ;
③、-- 殺死程序
kill 17 ;
(2)、查詢事務,然後殺死程序
①、-- 檢視在鎖的事務
select * from information_schema.innodb_trx ;
②、-- 殺死程序,17為執行緒id(就是上面命令的trx_mysql_thread_id列)
kill 17 ;
-- 檢視當前鎖定的事務
select * from information_schema.innodb_locks ;
-- 檢視等鎖的事務
select * from information_schema.innodb_lock_waits ;
InnoDB之鎖機制
前兩天聽了姜老大關於innodb中鎖的相關培訓,剛好也在看這方面的知識,就順便利用時間把這部分知識做個整理,方便自己理解。主要分為下面幾個部分 1.innodb同步機制 innodb儲存引擎有兩種同步機制選擇,一種是mutex,其是完全的互斥方法。另一種是rw lock,可以給臨界資源加上s lat...
InnoDB之鎖機制
前兩天聽了姜老大關於innodb中鎖的相關培訓,剛好也在看這方面的知識,就順便利用時間把這部分知識做個整理,方便自己理解。主要分為下面幾個部分 1.innodb同步機制 innodb儲存引擎有兩種同步機制選擇,一種是mutex,其是完全的互斥方法。另一種是rw lock,可以給臨界資源加上s lat...
MySQL的InnoDB鎖機制
在innodb的事務隔離級別是可重複讀級別且innodb locks unsafe for binlog禁用的前提下,mysql的鎖機制經過測試為 1.當update和delete操作的時候,mysql的加鎖機制大概為三步 1 對where條件後面的條件進行鎖索引區域操作,如果沒有壓上索引,則整個索...