高性能Mysql(一)
大家好我是孫嵓,從今天起帶大家走進高性能Mysql的世界,讓你清晰的認識Mysql以及如何最大限度的去優化Mysql,提高我們數據的查詢速度,保證我們的業務順利的進行。
Mysql服務器邏輯架構
讀寫鎖
讀鎖(read lock)和寫鎖(write lock)也被稱為共享鎖(shared lock)和排他(exclusive lock)鎖
讀鎖是共享的互不干擾的,多個客戶在同一時刻可讀取同一資源,互不打擾。
寫鎖則是排他的,一個寫鎖會阻塞其他的寫鎖和讀鎖,確保在給定的時間,只有一個用戶能執行寫入,防止其他用戶讀取正在寫入的資源。
鎖粒度
顧名思義鎖的粒度大小,這里表示鎖的數據范圍鎖的是部分還是整體。任何時候在給定的資源,鎖定的數據量越少,則并發的程度越高,只要不發生沖突即可,這句話很精辟。
 但是加鎖會消耗資源。包括獲取鎖、檢查鎖是否解除以及釋放鎖,都會增加系統開銷。
 Mysql的各種存儲引擎都可以實現自己的鎖策略和鎖粒度。
 鎖策略就是在鎖的開銷和數據的安全性之間尋求平衡,大部分都是在表上加行級鎖,然后再以各種復雜的方式來實現。
表鎖(table lock)
表鎖是開銷最小的鎖策略,它對整張表進行加鎖一用戶對表進行寫操作時(插入、刪除、更新等),需要先獲得鎖,阻塞其他用戶對表的所有讀寫操作。只有沒有寫鎖時其他用戶才能獲取讀鎖。
寫鎖比讀鎖有更高的優先級,因此一個寫鎖請求可能會被插入到讀鎖隊列前面(寫鎖可以插入讀鎖前面,讀不能插入到寫鎖前面)
場景:ALTER TABLE之類的語句會使用表鎖,忽略了存儲引擎的鎖機制。
行鎖(row lock)
行級鎖可以最大程度的支持并發處理(開銷大)。在InnoDB和XtraDB,以及其他一些存儲引擎中實現了行級鎖。
事務
**ACID(Atomicity Consistency Isolation Durability)**相信大家不陌生吧,很經典的面試題啊。
 在這里我通過一個例子帶大家領略一下ACID四大特性。
 假設:銀行數據庫現在有兩張庫表:支票表和儲蓄表。現在要從用戶孫嵓支票賬戶轉移200rmb到他的儲蓄賬戶,那么至少需要三個步驟:
這三個操作打包在一個事務中,任何一個步驟失敗,則必須回滾所有的步驟,保證數據。
 
原子性(Atomicity)
整個事務的操作要么全部成功,要么全部失敗
一致性(Consistency)
我的錢從那個賬戶轉到另一個賬戶,總量是沒變的,只不過從一個賬戶到了另一個賬戶;即使上述3,4語句崩潰了,事務會回滾200rmb還是再支票賬戶里。
隔離性(Isolation)
通常來說,一個事務所做的修改在最終提交以前,對其他事務是不可見的。比如我執行完第三句時,第四句還沒開始時,此時有另外一個賬戶匯總程序開始運行,這個時候查到的余額沒有被減去200rmb。這個跟后面講到的隔離級別有關聯。
持久性(Durability)
一旦事務提交了,所做的修改就會永久保存到數據庫中。
這種事務極大的保證了數據的安全性,但是像我們鎖一樣額外增加了系統的開銷,要對這些額外的開銷做優化正是Mysql存儲引擎的架構之處,用戶可根據業務是否需要事務處理去選擇合適的引擎,即使不支持事務的引擎可通過LOCK TABLES來提供一定程度的保護。
隔離級別
Sql標注定義了四種隔離級別,Mysql默認的隔離級別REPEATEABLE READ(可重復讀)
READ UNCOMMITED(未提交讀)
事務中的修改,對其他事務都是可見的即事務可以讀取為提交的數據稱為臟讀(Drity Read),例如上述隔離性的例子,他是可以看到賬戶已經減掉200rmb了。
READ COMMITED(提交讀)
一個事務只能看到已經提交的事務所做的修改 (解決了臟讀)。但是當一個A事務開始查詢X數據之后另一個B事務提交對X數據的修改,A事務再次查詢發現數據被修改了這種場景也被稱為不可重復讀(nonrepeatable read)。
REPEATEABLE READ(可重復讀)
一個事務中保證多次讀取同樣記錄的結果是一致的(解決了不可重復讀)。但是會導致幻讀(Phantom Read)指的是A事務讀取某個范圍的的記錄,B事務在該范圍內插入了一條新紀錄,A事務再次讀取的此范圍的時候會產生幻行(Phantom Row)。InnoDB和XtraDB存儲引擎通過**多版本并發控制(MVCC,Multiversion Concurrency Contral)**解決了幻讀問題。
SERIALIZABLE(可串行化)
最高的隔離級別,強制事務串行化,避免了所有問題。簡單來書會在讀取的每一行數據上都加鎖,所以會導致大量的超時和鎖爭用的問題。只有在非常需要確保數據的一致性而且可以接受沒有并發的情況下,才考慮使用
放一張隔離級別的對比圖:
 
死鎖
兩個或者多個事務在同一資源上相互占用,并請求鎖定對方占用的資源,導致惡性循環的現象。多個事務試圖以不同的順序鎖定資源時,就可能會產生死鎖。多個事務同時鎖定同一個資源時,也會產生死鎖。
 提供一個場景:
 
如果湊巧兩個事務都執行了第一條語句,更新了一行數據,同時也鎖定了該行數據,接著事務都嘗試去執行第二條update,卻發現該行被對方鎖定,兩個事務都在等待對方釋放鎖,同時又持有對方需要的鎖,則陷入了死循環。除非有外部因素介入才能解除死鎖。
 
死鎖發生后,只有部分或者完全回滾其中一個事務,才能打破死鎖
 事務日志
事務日志
可以幫助提高事務的效率。簡單來說使用事務日志,存儲引擎在修改表數據時只需要修改其內存拷貝,再將該行為持久在硬盤上的事務日志中,而不用每次將修改的數據本身持久到磁盤。事務日志采用追加的方式,寫日志操作磁盤一小塊區域順序I/O,而不像隨機I/O需要在磁盤多地方移動磁頭。事務日志持久后,內存中修改的數據在后臺可慢慢刷新回到磁盤即預寫式日志(Write-Ahead Loggin),修改數據需要寫兩次磁盤。
以上就是本文的全部內容了,能力有限,理性對待
如果感覺還不錯的話,歡迎點贊和關注🦋
分享經驗,貼近項目,crud永不為奴!!!
歡迎大家關注我的公眾號,公眾號也會實時發布Java項目相關的文章!!!
 1.一文搭建本地git服務器
2.Java實現短信驗證碼
3. 搭建本地git服務
總結
以上是生活随笔為你收集整理的高性能Mysql(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: shiro学习(10):servelet
- 下一篇: 最新ui设计趋势_10个最新且有希望的U
