高併發下MySQL事務以及優化
MySQL有一個最大的緩衝區 Buffer Pool(預設大小128M),用來快取 頁 ,將查詢到的頁放到 Buffer Pool
這時有一個 free連結串列,頭節點儲存了當前連結串列的元素個數以及下一個連結串列在哪裡,後續的連結串列儲存 Buffer Pool裡哪些區域是空閒的,當空閒的Buffer Pool的區域被使用的時候,相應的free連結串列的節點也被刪除
同時又有一個 lru連結串列,頭節點也是儲存了當前連結串列的元素個數,來將在free連結串列中刪除的節點加入到 lru連結串列中的頭節點後面,使用最近最少使用演算法,最近被使用節點也會放到頭節點後面,
當再一次更新中,Buffer Pool 中所有的資料全部換掉, 這一行為被稱作換血
為了避免換血這種情況發生,MySQL對 lru 連結串列進行了升級,前 5/8 的部分用來儲存熱資料,也就是經常訪問的資料,後 3/8 的部分用來儲存冷資料,也就是不是經常被訪問的資料,而且冷資料也可以升級成為熱資料,當一個冷資料被連續訪問,而且兩次訪問時間相差大於1s,t2 - t1 > 1s,避免一個SQL語句連續訪問多次冷資料,這時候這頁冷資料就升級成為了熱資料,同時最後一條熱資料被淘汰掉成為冷資料。
前 1/4 的熱資料沒有必要交換,也就是沒必要看誰是最長被訪問的資料,因為會造成前面的熱資料進行多次沒有意義的交換,本質是:這是淘汰的機制,而不是找出最熱的機制,沒有必要浪費時間
Buffer Pool裡面肯定有一些頁是被修改的,我們稱之為髒頁,MySQL內建了執行緒 定時地更新髒頁
類似free連結串列,當Buffer Pool中有頁被update 更新修改之後,會放在 flush連結串列頭節點後面,之後內建定時更新地執行緒 會在連結串列裡面找相應的地址來進行更新
對於更新髒頁,MySQL有兩個 Redo Log日誌,專門來儲存髒頁相關地日誌,當兩個日誌全都儲存滿了之後或者後臺執行緒定時地 就開始更新髒頁進行持久化,這就完成了從隨機IO到順序IO地轉變
但是,有可能在進行事務的時候兩個日誌滿了必須進行持久化,就會讓事務滯後,這時我們可以進行對Read Log 的配置,讓空間變大或者數量變多。但是同樣有弊端,當MySQL因為一些原因掛掉的話,需要依靠 Read Log 日誌進行資料的恢復,就回導致開啟MySQL的速度變慢