InnoDB日誌管理機制(二) – 運維派
一個BufferPool例項中的所有控制頭資訊連續儲存在一起,所以控制資訊儲存完成之後才是真正的緩衝頁面,下圖表示的是一個BufferPool例項的記憶體分佈情況。
對於BufferPool中的所有頁面,都有一個控制頭資訊與它對應,從上圖可以看出,每一個ctl都表示了一個屬於自己的page使用情況。初始化例項時當然還需要對每一個控制頭資訊進行初始化,也就是每一個buf_block_t結構。初始化一個頁面控制資訊是通過buf_block_init函式實現的,buf_block_t結構中包含了很多資訊,主要包括如下4部分。
- 其對應的頁面地址frame。
- 頁資訊結構buf_page_t,這個結構用來描述一個頁面的資訊,包括所屬表空間的ID號、頁面號、被修改時產生的LSN(newest_modification及oldest_modification)、使用狀態(現在共有9種狀態)等(上面已經介紹過與buf_block_t的關係)。
- 用來保護這個頁面的互斥量mutex。
- 訪問頁面時對這個頁面上的鎖lock(read/write)等。
在初始化完每一個頁面之後,需要將每一個頁面加入到上面提到的空閒頁連結串列中,因為這些頁面現在的狀態都是未使用(BUF_BLOCK_NOT_USED)。
到現在為止,緩衝池的一個例項就算初始化完成了,在訪問資料庫的時候會通過這些記憶體頁面來快取檔案資料。
相對於整個Buffer Pool而言,多個Buffer Pool例項之間的關係,需要在這裡再講述一下。上面所說的單個例項的初始化,是完全獨立的,多個例項之間沒有任何關係,單獨申請、單獨管理、單獨刷盤,可以從其實現的程式碼中看到這一點,程式碼如下。
從程式碼中可以看出,每一個Buffer Pool例項在整個Buffer Pool中確實是完全獨立的,而在具體使用時,針對不同頁面,通過一個HASH演算法,來對映到一個具體的例項中,對應的程式碼如下。
通過Buffer Pool多例項的管理機制,可以減少系統執行過程中不同頁面之間一些操作的相互影響,從而很好地解決了由於頁面之間的資源爭搶導致的效能低下的問題,所以在實際的運維過程中,建議要分多例項的管理方式,把MySQL及InnoDB用好,讓業務少一些煩惱。
本文先到這裡,下次開始講REDO LOG,那是一大塊…….
文章來自微信公眾號:DBAce