死鎖
死鎖是指兩個或者多個事務(wù)在同一資源上相互占用,并請求鎖定對方占用的資源,從而導(dǎo)致惡性循環(huán)的現(xiàn)象,多個事務(wù)同時鎖定同一資源時,也會產(chǎn)生死鎖。
比如:
事務(wù)開始
Asession:
1更新A表id1的字段
2更新A表id2的字段
Bsession:
1更新B表id2的字段
2更新A表id1的字段
ABsession都開啟事務(wù)后同時執(zhí)行了1,那么id1,2都因為更新是排它鎖,鎖住了
都會去執(zhí)行第二條sql,就執(zhí)行不成功了。互相沒有釋放鎖。
mysql會自己處理。
把持有行級鎖最少的那一條事務(wù)回滾最后一條
如果行鎖個數(shù)相同,回滾最后嘗試獲取鎖的事務(wù)。
事務(wù)日志
事務(wù)可以回滾和提交是因為事務(wù)日志
通過事務(wù)日志實現(xiàn)回滾
在為提交之前沒有存在數(shù)據(jù)庫文件上
寫日志的操作是磁盤上一小塊區(qū)域內(nèi)的順序I/O,而不像隨機I/O需要在磁盤的多個地方移動磁頭,所以采用事務(wù)日志的方式相對來說要快得多。事務(wù)日志持久以后,內(nèi)存中被修改的數(shù)據(jù)在后臺可以慢慢的刷回到磁盤。目前大多數(shù)存儲引擎都是這樣實現(xiàn)的,我們通常稱為預(yù)寫式日志,修改數(shù)據(jù)需要些兩次磁盤。
如果數(shù)據(jù)的修改已經(jīng)記錄到事務(wù)日志并持久化,但數(shù)據(jù)本身還沒有寫回磁盤,此時系統(tǒng)崩潰,存儲引擎在重啟時能夠自動恢復(fù)這部分修改的數(shù)據(jù)。
多版本并發(fā)控制(MVCC)
MySQL中大多數(shù)事務(wù)型存儲引擎實現(xiàn)都不是簡單的行級鎖?;谔嵘l(fā)性能考慮,他們一般都同時實現(xiàn)了多版本并發(fā)控制(Multi-Version Concurrency Control,MVCC).
Oracle等其他數(shù)據(jù)庫也實現(xiàn)了MVCC,但是各自實現(xiàn)機制不盡相同,以為MVCC沒有一個統(tǒng)一的實現(xiàn)標準。
可以認為MVCC就是行級鎖的一個變種,但是他在很多情況下避免了加鎖操作。
MVCC是通過保存數(shù)據(jù)在某個時間點的快照來實現(xiàn)的。也就是說,不管一個事務(wù)需要執(zhí)行多長時間,每個事物看到的數(shù)據(jù)都是一致的。
根據(jù)事務(wù)開始時間的不同,不同事務(wù)對同一張表,在同一個時刻看到的數(shù)據(jù)可能是不一樣的。
MVCC有很多種版本的實現(xiàn),在InnoDB引擎下MVCC是通過在每行記錄后面保存兩個隱藏的列來實現(xiàn)的。
一列保存了行的創(chuàng)建時間(版本),一列保存了行的刪除時間(版本)。存儲的并不是實際的時間值,而是系統(tǒng)版本號。
每開始一個新的事務(wù),系統(tǒng)版本號都會自動遞增。事務(wù)開始時刻的系統(tǒng)版本號會作為事務(wù)的版本號,用來和查詢中每行記錄的版本號進行比較。
比如在REPEATABLE TABLE隔離級別下:
Insert: 為新插入的每一行記錄保存當前系統(tǒng)版本號作為行版本號。
Delete:為刪除的每一行保存當前系統(tǒng)版本號作為刪除版本號。
Update:插入一行新的記錄,保存當前系統(tǒng)版本號作為行版本號,同時保存當前系統(tǒng)版本號為原來的行作為刪除版本號。
Select:
1.只查找版本號早于當前事務(wù)版本的數(shù)據(jù)行(也就是,行的系統(tǒng)版本號小于或等于事務(wù)的系統(tǒng)版本號);這樣可以確保事務(wù)讀取的行,要么是在事務(wù)開始前已經(jīng)存在的,要么是事務(wù)自身插入或修改過的。
2.行的刪除版本號要么沒有,要么大于當前事務(wù)版本號。這樣可以確保事務(wù)讀取到的行,在事務(wù)開始之前未被刪除。
MVCC只在REPEATABLE READ和READ COMMITTED兩個隔離級別下工作。因為READ UNCOMMITTED總是讀取最新的數(shù)據(jù)行,而不是符合當前事務(wù)版本的數(shù)據(jù)行。
而SERIALIZABLE則會對所有讀取的行都加鎖。
注意:需要周期性的整理,來真實的刪除老的、過期的數(shù)據(jù)。
InnoDB 有預(yù)讀
根據(jù)局部性原理預(yù)讀一部分數(shù)據(jù)
數(shù)據(jù)庫優(yōu)化方面
1 硬件優(yōu)化
2 系統(tǒng)配置優(yōu)化
3 數(shù)據(jù)庫表結(jié)構(gòu)優(yōu)化
4 SQL索引優(yōu)化