日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql运维机制_《MySQL运维内参》节选 | InnoDB日志管理机制(一)

發布時間:2025/3/12 数据库 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql运维机制_《MySQL运维内参》节选 | InnoDB日志管理机制(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引 子

InnoDB 存儲引擎是支持事務ACID特性的,它是以二十多年前IBM的一篇著名文章《ARIES:A Transaction Recovery Method Supporting Fine-Granularity Locking and PartialRollbacks Using Write-Ahead Logging》為理論基礎,大多數關系型數據庫的實現都是基于這個理論的,包括Oracle、DM等。

這個理論基本就是一個關系型數據庫相關的數據庫恢復原型設計,包括日志、回滾、REDO、并發控制、BufferPool管理等方面,內容非常全面。同時,這些內容是一個不可分割的整體,它們的共同目標之一就是保證數據庫數據的一致性,保證數據庫事務的ACID特性,所以這一節要講的東西都是互相遷連的,它們之間相互作用,相互配合,相互驅動,才能保證數據庫的數據完整性。下面就先從Buffer Pool的背景和實現開始講起。

仔細說說InnoDB Buffer Pool

Buffer Pool的背景

InnoDB的Buffer Pool主要用來存儲訪問過的數據頁面,它就是一塊連續的內存,通過一定的算法可以使這塊內存得到有效的管理。它是數據庫系統中擁有最大塊內存的系統模塊。

InnoDB存儲引擎中數據的訪問是按照頁(有的也叫塊,默認為16K)的方式從數據庫文件讀取到Buffer Pool中的,然后在內存中用同樣大小的內存空間來做一個映射。為了提高數據訪問效率,數據庫系統預先就分配了很多這樣的空間,用來與文件中的數據進行交換。訪問時按照最近最少使用(LRU)算法來實現Buffer Pool頁面的管理,經常訪問的頁面在最前面,最不經常的頁面在最后面。如果Buffer Pool中沒有空閑的頁面來做文件數據的映射,就找到Buffer Pool中最后面且不使用的位置,將其淘汰,然后用來映射新數據文件頁面,同時將它移到LRU鏈表中的最前面。這樣就能保證經常訪問的頁面在沒有刷盤的情況下始終在Buffer Pool中,從而保證了數據庫的訪問效率。

Buffer Pool的大小可以在配置文件中配置,由參數innodb_buffer_pool_size的大小來決定,默認大小為128M。在MySQL 5.7.4之前,一旦MySQL已經啟動,這個值便不能再做修改,如果需要修改,只能退出MySQL進程,然后修改對應的配置文件來設置新的Buffer Pool大小,重新啟動后才能生效。這在運維上非常不方便,因為很多時候,需要去調整Buffer Pool的大小,特別是在單機多實例,或者提供云數據庫服務的情況下,我們需要根據用戶及實際業務的需要,不斷地去動態增加或減少Buffer Pool size,從而合理地利用內存及優化數據庫。

讓人慶幸的是,MySQL官方也發現了這種不便。在MySQL 5.7.5之后,MySQL在源碼上改變了對Buffer Pool的管理,可以在MySQL進程運行的情況下,動態地配置innodb_buffer_pool_size。另外,需要強調的是,如果Buffer Pool的大小超過了1GB,應該通過調整 innodb_buffer_pool_instances=N,把它分成若干個instance的做法,來提升MySQL處理請求的并發能力,因為Buffer Pool是通過鏈表的方式來管理頁面的,同時為了保護頁面,需要在存取的時候對鏈表加鎖,在多線程的情況下,并發去讀寫Buffer Pool里面緩存的頁面需要鎖的競爭和等待。所以,修改為多個instance,每個instance各自管理自己的內存和鏈表,可以提升效率。

Buffer Pool實現原理

在啟動MySQL服務時,會將所有的內嵌存儲引擎啟動,包括InnoDB。InnoDB會通過函數buf_pool_init初始化所有的子系統,其中就包括了InnoDB Buffer Pool子系統。Buffer Pool可以有多個實例,可以通過配置文件中的參數innodb_buffer_pool_instances來設置,默認值為1,實現多實例的Buffer

Pool主要是為了提高數據頁訪問時的并發度。每個實例的空間大小都是相同的,也就是說系統會將整個配置的Buffer Pool大小按實例個數平分,然后每個實例各自進行初始化操作。

在代碼中,一個Buffer Pool實例用buf_pool_t結構體來描述,這個結構體是用來管理Buffer Pool實例的一個核心工具,它包括了很多信息,主要有如下幾個部分。

1. FREE鏈表,用來存儲這個實例中所有空閑的頁面。

2. flush_list鏈表,用來存儲所有被修改過且需要刷到文件中的頁面。

3. mutex,主要用來保護這個Buffer Pool實例,因為一個實例只能由一個線程訪問。

4. chunks,指向這個Buffer ?Pool實例中第一個真正內存頁面的首地址,頁面都是連續存儲,所以通過這個指針就可以直接訪問所有的其他頁面。

上面的兩個鏈表,管理的對象是結構體buf_page_t,這是一個物理頁面在內存中的管理結構,是一個頁面狀態信息的結合體,其中包括所屬表空間、Page

ID、最新及最早被修改的LSN值(最早LSN信息會在做檢查點時使用,后面將會講到),以及形成Page鏈表的指針等邏輯信息。實際上,這個結構是被另一個結構管理的,它是buf_block_t,buf_block_t與buf_page_t是一一對應的,都對應BufferPool中的一個Page,只是buf_page_t是邏輯的,而buf_block_t包含一部分物理的概念,比如這個頁面的首地址指針frame等。關于buf_block_t,后面還會繼續介紹。

初始化一個Buffer Pool實例內存空間的函數是buf_chunk_init。一個Buffer

Pool實例的內存分布是一塊連續的內存空間,這塊內存空間中存儲了兩部分內容,前面是這些數據緩存頁面的控制頭結構信息(buf_block_t結構),每一個控制頭信息管理一個物理頁面,這些控制頭信息的存儲,占用了部分Buffer

Pool空間,所以在運維過程中,看到狀態參數innodb_buffer_pool_bytes_data總是比innoDB_buffer_pool_size小,就是因為控制頭信息占用了部分空間。實際的分配方式是,Buffer Pool頁面從整個實例池中從后向前分配,每次分配一個頁面,而控制結構是從前向后分配,每次分配一個buf_block_t結構的大小,直到相遇為止,這樣就將一個實例初始化好了。但一般情況下,中間都會剩余一部分沒有被使用,因為剩余的空間不能再放得下一個控制結構與一個頁面了。相應的分配代碼如下。

其中,`chunk->size`是在前面提前根據Buffer Pool實例內存大小計算出來的,可以存儲的最多的Page及Page對應控制結構的個數。

限于篇幅,本文第一部分結束。

文章來自微信公眾號:DBAce

本文鏈接:http://www.yunweipai.com/15532.html

總結

以上是生活随笔為你收集整理的mysql运维机制_《MySQL运维内参》节选 | InnoDB日志管理机制(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。