大叔, 據說你入職了一家新公司?mysql
大叔詫異的看了我一眼, 問你這個傢伙咋知道的?git
我看你的脈脈更新了啊.sql
年輕人你剛入職場沒多久, 就別成天看脈脈了, 有這時間還不如多學習會兒呢.數據庫
大叔從地鐵站出來, 須要打開億通行APP, 獲取到一個地鐵站二維碼, 掃碼後對應的通道閘機就會打開.markdown
正常狀況下, 錢扣了閘機打開了,此次交易就結束了.併發
大叔坐地鐵的場景映射到數據庫有如下概念:mvc
出站扣費看做一個原子.高併發
掃碼出站後扣費, 不能扣了大叔的錢, 閘機還不打開, 這樣大叔確定會跳起來的.性能
不扣帳戶的錢, 閘機自動給大叔打開, 大叔開心了, 這個地鐵運營公司也不幹.學習
掃碼閘機打開, 只能大叔本身經過高峯時期排隊也有可能本身掃碼讓別人進去了(咱們通常經過人工智能保證隔離性)
大叔乘進站和出站要有乘車記錄, 咱們須要將它固化下來.
原子性+隔離性+持久性 組成了一致性
在數據庫中, 咱們稱以上爲事務(ACID), 事務是必須知足原子性、隔離性、一致性和持久性的.
一致性是基礎,也是最終目的,其餘三個特性(原子性、隔離性和持久性)都是爲了保證一致性的 在比較簡單的場景(沒有高併發)下,可能會發生一些數據庫崩潰等狀況,這個時候,依賴於對日誌的 REDO/UNDO 操做就能夠保證一致性 而在比較複雜的場景(有高併發)下,可能會有不少事務並行的執行,這個時候,就極可能致使最終的結果沒法保證一致性.
每週五下午, 大叔所在的小組就須要把這周的工做進度同步到 wiki 一個週報裏.
由於人多集中時間寫, 好屢次提交都跟其餘同事衝突, 大叔經過學習數據庫隔離級別概念的思路解決了這個問題, 咱們來看看他是怎麼作的吧.
同事小王還沒提交工做進度, 就被我看到了(嘿嘿~), 這種咱們稱爲髒讀問題.
同事小王提交了工做進度, 又被我看到了, 這種咱們稱爲不可重複讀.
同事小王提交了工做進度, 可是當前我沒退出編輯狀態, 仍是我以前讀到的數據(可重複讀)
可是~ 小李新增的進度咋展現出來了...(新插入數據致使幻讀)
上面三個方案看起來一個比一個好, 可是都有點問題, 大叔會心一笑, 心想我在學 mysql小冊 時候就知道這些問題啦, 徹底能夠靠最高隔離級別-串行化解決
因而組內提議: 同時只有一我的可讀寫, 提議誰要編輯在羣裏說一下, 改完後再通知下一我的再操做吧, 這樣就能夠避免衝突.
然而串行化雖然能夠避免衝突, 可是對於性能影響過大, 當通知下一我的時候, 若是下一我的遲遲不回覆, 可能須要等一段時間確認會浪費一些時間.
大叔又仔細想了想, git 提交代碼也是每一個人同時進行, 爲何寫個 wiki 這就這麼費勁呢?
咱們每一個人基於當前本身的改動生成一個版本, 提交後與最新版本比對, 解決衝突.
MVCC,全稱Multi-Version Concurrency Control,即多版本併發控制.
主要是爲了提升數據庫併發性能,用更好的方式去處理讀-寫衝突,作到即便有讀寫衝突時,也能作到不加鎖,非阻塞併發讀, InnoDB 事務的可重複讀和讀取已提交隔離等級就是經過 mvcc+undo 實現的.
還記得咱們上一回合介紹的 InnoDB 行記錄上隱藏了兩個列爲 事務trx_id 和 roll_pointer.
多個事務對 InnoDB 更改記錄, 都會對應記錄一條 undo日誌, 每條 undo日誌 也都有一個 roll_pointer 屬性, 記錄指向下一條 undo日誌 的指針, 組成一個鏈表, 事務提交後 undo日誌 刪除.
大叔的工做地點坐落在中關村某棟大廈裏, 比較幸運的是大廈負一層就有一個食堂餐廳, 中午坐電梯就能夠直接到了(固然擠電梯也不容易)
上次就由於大叔點了一份魚香肉絲蓋飯, 由於商家作的時候發現沒有魚肉, 去提早採購, 致使大叔等了一個小時才吃到飯(困~).
大叔給商家想了一個辦法, 每次客戶的要求都要寫到服務單中, 防止因服務員過於忙碌(服務崩潰)而忘了以後作的事情, 服務員只需按照服務單作事便可.
WAL(write ahead log) 預寫式日誌, 解決了服務崩潰數據恢復問題, 關鍵點在於先寫日誌再寫磁盤, 在對數據頁進行修改時, 經過將"修改了什麼"這個操做記錄在日誌中, 而沒必要立刻將更改內容刷新到磁盤上, 從而將隨機寫轉換爲順序寫, 提升了性能.
mysql 的 WAL 跟 redo log 是一回事, 一般是物理日誌, 記錄的是數據頁的物理修改, 而不是某一行或某幾行修改爲怎樣怎樣, 它用來恢復提交後的物理數據頁(恢復數據頁,且只能恢復到最後一次提交的位置)
大叔給商家說, 若是發現食材不夠了, 就讓撤銷訂單好了, 把以前的付費記錄查出來退錢, 我再從新下單.
undo log用來回滾行記錄到某個版本。undo log通常是邏輯日誌,根據每行記錄進行記錄.
多個事務對 InnoDB 更改記錄, 都會對應記錄一條 undo日誌, 可重複讀的隔離級別也是利用了undo log.
大叔終於找到了工做, 也沒時間跟我聊天說話了, 固然這也是 mysql 最後一回合了, 但願大叔可以在以後的職場和生活中順利~