一、資料庫引擎
mysql常用的資料庫引擎也就是myisam和innodb兩種,相比較起myisam而言innodb支援了事務、外來鍵等功能,具有更好的併發性支援,所以在大併發的情況的下我們一般選擇的是innodb來作為我們的資料庫儲存引擎,而myisam相較innodb的執行效能上會有更好的表現,(畢竟myisam是mysql自帶的引擎,而innodb是由別人寫的)。mysql鎖級別包括三種:表鎖(對整個表加鎖)、頁鎖(介於表鎖和行鎖之間)、行鎖(對具體行加鎖),對於myisam預設採用的是表鎖,而對於innodb預設採用的是行鎖,
innodb的行鎖是通過共享鎖和排他鎖實現的,具體參考mysql鎖機制之共享鎖和排它鎖,
共享鎖:select * from table_name where .....lock in share mode
排他鎖:select * from table_name where .....for update
由於mysql事務預設是自動提交的,如果要測試鎖機制,記得把事務自動提交關閉
set autocommit=0
二、資料庫事務
事務具有acid的特性,也就是原子性、永續性、隔離性和一致性,mysql中innodb支援事務,而myisam不支援,採用事務對於業務邏輯和併發都有很大的幫助,但是採用事務也會導致相應的問題,
1、丟失更新:兩個事務同時對同一行進行修改,會有乙個事務的更新被覆蓋。(寫寫)
2、髒讀:乙個事務對一行記錄進行讀取,另乙個事務同時對這行記錄進行修改,如果寫事務中途失敗回滾,而讀事務卻讀取到寫事務修改的值,這樣就造成了髒讀。(讀寫)
3、不可重複讀:乙個事務對一行記錄進行兩次讀取,另乙個事務同時對這一行進行修改,這個會導致第一次讀取的記錄和第二次讀取的記錄不一致,出現了不可重複讀。(讀寫讀)
4、幻讀:乙個事務對錶進行兩次讀取,另乙個事務同時進行插入操作,這回導致第二次讀取出現 了第一次沒有出現的記錄,也就是幻讀。
解決辦法也就是設定事務的隔離級別:讀未提交(read-uncommitted)、讀提交(read-committed)、可重複讀(read-reapted)、序列化(serializable)。
事務的隔離級別越高,那麼出現事務也就越安全,但是加鎖機制也就越複雜,效能消耗越大。
mysql預設採用的是可重複讀的級別
select @@tx_isolation 可以檢視
三、innodb的行鎖
innodb預設採用的是行鎖,但是採用行鎖必須要查詢條件為索引列,如果查詢條件不是為索引列,那麼mysql會採用表鎖機制。接下來就來做一下驗證。
1、建乙個簡單的表:
create table test(
a int null,
b int null,
index a_index (a) using btree
)engine=innodb;
這個表有兩列a和b,都是int型別,其中a是建了索引,
插入四行:
insert into test(a,b) values(1,2);
insert into test(a,b) values(3,4);
insert into test(a,b) values(3,6);
insert into test(a,b) values(8,2);
2、 開啟兩個session:
session1
sessio2
set autocommit=0
set autocommit=0
select * from test where b=4 for update;
正確查詢出結果
select * from test where b =6 for update;
查詢被鎖死,處於等待狀態
commit
表鎖被釋放,查詢出結果,commit
select * from test where a =1 for update;
正確查詢出結果
select * from test where a=8 for update;
正確查詢出結果,a是索引列,where條件使用索引列,預設採用行鎖機制。
commit
commit
...... for update 是加排它鎖。接下來驗證事務是否採用行鎖。
session1
session2
set autocommit=0
set autocommit=0
start transaction
start transaction
update test set a=10 where b=4 for update;
正確更新
update test set a=20 where b=6 for update;
更新等待,出現表鎖,
commit
鎖被釋放,正確更新,commit
update test set b=10 where a=10 for update;
正確更新
update test set b=20 where a=20 for update;
正確更新,a是索引列,where條件使用索引列,預設採用行鎖機制,不同行不會被鎖死
commit
commit
innodb的行鎖在查詢條件為索引列的情況下才採用,所以查詢條件盡量採用索引列。
間隙鎖innodb中面對between...and....這種區間查詢的時候採用的是間隙鎖機制,
update test set a=.... where b between x and y 那麼從[x,y]這個區間都會加上行鎖。
四、總結
1、在開發過程中盡量降低事務的粗粒度,避免過多的查詢和更新和插入操作堆在一起,從而造成長時間的鎖等待。
影響程式執行效率。
2、查詢條件盡量採用索引列,從而使mysql採用行鎖,而不是表鎖。
3、使用區間查詢的時候注意區間範圍,避免鎖住其他不必要鎖住的行。
4、合理的採用事務的隔離級別,事務隔離級別越高,效能越低,鎖機制越複雜,發生的死鎖的概率越大,
有時候降低事務的隔離級別也是解決死鎖的有效方式。
MySql中InnoDB引擎索引
mysql中innodb引擎的索引分兩類,一類是一級索引 主鍵的同義詞 一類是二級索引 非主鍵的索引 兩類索引都使用b tree形式組織,但一級索引的葉子節點包含所以對應的整行資訊,所有的查詢最終都是通過一級索引完成,二級索引只包含二級索引對應的一級索引。所以直接使用一級索引比用二級索引快,因為少了...
Mysql中InnoDB引擎的鎖
鎖這種機制的作用 對共享資源併發訪問的管理,保證資料的完整性和一致性。在資料庫中,lock與latch都可以被稱為 鎖 但是兩者的含義是完全不同的。lock針對的物件是事務,它用來鎖定資料庫中的物件,如表 頁 行。一般lock的物件僅在事務commit或者rollback後進行釋放,並且lock是有...
MySql中啟用InnoDB資料引擎
1.mysql支援的資料引擎列表如下 2.其中預設的是myisam資料引擎,可惜此引擎不支援事務處理,我們需要將預設的資料引擎改為innodb。3.innodb和berkeleydb支援事務處理,可惜預設的情況下都是被disable的。所有的引擎裡面,innodb效能最強大,算是商業級的。4.啟動i...