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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

禁用内存清理_MySql那些事儿(二):InnoDB架构介绍之内存篇

發(fā)布時(shí)間:2023/12/19 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 禁用内存清理_MySql那些事儿(二):InnoDB架构介绍之内存篇 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

作者:阿茂

InnoDB介紹

書接上回,我們基本說完了mysql的邏輯架構(gòu)與物理架構(gòu)。今天我們來說說當(dāng)下比較火的存儲(chǔ)引擎InnoDb。MySQL 5.5以前InnoDB引擎是需要手動(dòng)通過Plugin方式引入,內(nèi)置的是MyISAM。MySQL 5.5以后隨著數(shù)據(jù)庫默認(rèn)引擎的更換,InnobaseOy的InnoDB就開始大放異彩(以下我們將用MySQL5.7舉例)。我們先說說它有什么樣的特性讓諸位英雄都說香:

  • 免費(fèi):這個(gè)在當(dāng)時(shí)Oracle,DB2,Sybase MSSQL壟斷的時(shí)代,有一款免費(fèi)還相對穩(wěn)定的的數(shù)據(jù)庫,再加上后期社區(qū)非常活躍,能不香嗎?
  • 完善的崩潰恢復(fù)機(jī)制:不管是服務(wù)器硬件故障還是挖掘機(jī)挖斷電線導(dǎo)致的關(guān)機(jī),重啟數(shù)據(jù)庫后都無需執(zhí)行任何操作(根據(jù)設(shè)置參數(shù)有關(guān)) 崩潰恢復(fù)會(huì)自動(dòng)完成崩潰之前已提交的所有更改,并撤消正在處理但尚未提交的所有更改。只需重新啟動(dòng),然后從上次中斷的地方繼續(xù)即可。
  • 高效的緩存查詢機(jī)制:通過一些算法和設(shè)計(jì)(后面會(huì)說到)讓常用的數(shù)據(jù)最大可能的基于內(nèi)存Buffer處理減少IO,通常這塊Buffer將高達(dá)數(shù)據(jù)庫服務(wù)器內(nèi)存的80%分配給它。
  • 完整性外鍵機(jī)制:將數(shù)據(jù)拆分到不同數(shù)據(jù)表中使用外鍵機(jī)制會(huì)自動(dòng)更新或刪除關(guān)聯(lián)表中的數(shù)據(jù)(現(xiàn)在基本沒有人這么玩了,一旦設(shè)計(jì)不全面, 數(shù)據(jù)的修改將不受程序的控制,數(shù)據(jù)耦合度太強(qiáng),適用于一些強(qiáng)制保證數(shù)據(jù)完整規(guī)范的系統(tǒng),例如工作流這類的)
  • 數(shù)據(jù)完整性校驗(yàn)機(jī)制:數(shù)據(jù)在磁盤或內(nèi)存中損壞,則校驗(yàn)機(jī)制會(huì)在使用前提醒您注意虛假數(shù)據(jù)
  • 自動(dòng)引入主鍵列:有適當(dāng)數(shù)據(jù)庫主鍵列時(shí)會(huì)自動(dòng)在Where子句,Order By子句,Group By字句后自動(dòng)引入主鍵。
  • 基于數(shù)據(jù)庫緩存Buffer寫數(shù)據(jù):不僅允許對同一表的并發(fā)讀寫訪問,而且還緩存更改的數(shù)據(jù)以減少磁盤IO。
  • 自適應(yīng)哈希索引 :當(dāng)頻繁的從巨表中查詢相同行的數(shù)據(jù)時(shí)候就會(huì)使用此方式,讓它們像從Hash表中查出來的一樣。
  • 表和索引壓縮:這個(gè)不用大多說了,它借助于zlib庫,采用L777壓縮算法。就是讓你在原來兩個(gè)數(shù)據(jù)頁中的數(shù)據(jù)現(xiàn)在一頁就能顯示下,但是過度壓縮會(huì)帶來重組頁的影響, 而且不是對所有類型數(shù)據(jù)列都有良好的壓縮比。
  • 動(dòng)態(tài)創(chuàng)建或刪除索引,保證數(shù)據(jù)的可用性(這個(gè)后面單獨(dú)說)
  • 截?cái)啾砜臻g非常快,并且可以釋放空間給系統(tǒng)重用。
  • 支持存儲(chǔ)引擎混用,最常見的就是我們關(guān)聯(lián)表查詢的時(shí)候產(chǎn)生的中間臨時(shí)表,默認(rèn)就是使用MEMORY引擎來實(shí)現(xiàn)的。
更多特點(diǎn)請參考閱讀最下方:Benefits of Using InnoDB Tables

###InnoDB內(nèi)存結(jié)構(gòu) 接下來我們來看一張InnoDB的邏輯架構(gòu)圖:

Buffer Pool

InnoDB使用malloc()操作在啟動(dòng)時(shí)為整個(gè)緩沖池分配緩存,緩沖池存儲(chǔ)著常訪問的表數(shù)據(jù)和索引,以頁面為單位(一個(gè)頁面可能包含多個(gè)行 )組成一個(gè)鏈接列表,使用LRU的變體算法將緩沖池作為列表管理。當(dāng)需要空間將新頁面加入到緩沖池時(shí),將淘汰掉最近最少使用的頁面,將其加入到列表的中間,通過此插入點(diǎn)將列表分為兩段:最前面的一段為最新訪問過的頁面,末尾是最近訪問的舊頁面,如下圖:該算法大致如下:

默認(rèn)情況下,3/8的緩沖池專用于舊的數(shù)據(jù)頁列表(Old SubList),當(dāng)然也可以(通過innodb_old_blocks_pct參數(shù)默認(rèn)是37,5-95范圍值)調(diào)整其比例大小。列表的中點(diǎn)(Midpoint)是新數(shù)據(jù)頁(New SubList)列表的尾部與舊數(shù)據(jù)頁(Old Sublist)列表的頭相交的邊界。當(dāng)一個(gè)頁面讀入緩沖池時(shí),它首先會(huì)插入舊列表(Old Sublist)的頭部如果再次讀取到舊列表(Old Sublist)的數(shù)據(jù)頁時(shí)(在一定時(shí)間內(nèi),由參數(shù)innodb_old_blocks_time來決定,默認(rèn)1000ms)將其移動(dòng)到新列表的的頭部。如果是用戶啟動(dòng)的操作需要讀取頁面,立即將其“年輕化”如果是預(yù)讀操作讀取該頁面第一次,不發(fā)生任何變化。隨著數(shù)據(jù)庫的逐漸運(yùn)行,中點(diǎn)數(shù)據(jù)的不斷插入,新老頁面都會(huì)隨著其他頁面的更新而老化,而最終未被使用到的頁面將到達(dá)舊列表的尾部被淘汰掉。

默認(rèn)情況下,查詢讀取的頁面會(huì)立即移入新的列表,它們在緩沖池中停留時(shí)間更長。例如,針對mysqldump操作或不帶WHERE的SELECT子句執(zhí)行的表掃描可以將大量數(shù)據(jù)載入緩沖池,并老化同等數(shù)量的舊數(shù)據(jù),即使不再使用新數(shù)據(jù)也是如此。預(yù)讀后臺(tái)線程加載且僅訪問一次的頁面將移到新列表的開頭。這些情況可能會(huì)將熱數(shù)據(jù)擠壓到舊的列表或者淘汰。我們可以通過以下幾種方法來優(yōu)化:

  • 調(diào)整innodb_old_blocks_pct參數(shù):為較小的值可以使僅讀取一次的數(shù)據(jù)不會(huì)占用緩沖池的很大一部分。掃描小型表時(shí),在緩沖池中移動(dòng)頁面的開銷較小,可以設(shè)置為較大值。
  • 防止緩沖池被預(yù)讀攪動(dòng):可以避免由于表或索引掃描而引起的類似問題,它們的特征是:通常快速連續(xù)地訪問數(shù)據(jù)頁面幾次,而再也不會(huì)被訪問。調(diào)整innodb_old_blocks_time (第一次訪問數(shù)據(jù)頁的時(shí)間窗口,單位MS,在該時(shí)間窗口內(nèi)可以訪問頁面而不將其移到New SubList的頭部),增加此值會(huì)使越來越多的塊從緩沖池中更快地老化。
  • 線程預(yù)讀:根據(jù)順序訪問的緩沖池中的頁面來預(yù)測很快需要哪些頁面。調(diào)整觸發(fā)異步讀取請求所需的順序頁面訪問數(shù)(innodb_read_ahead_threshold)參數(shù)來執(zhí)行預(yù)讀操作。 InnoDB僅當(dāng)讀取當(dāng)前擴(kuò)展區(qū)的最后一頁時(shí),才計(jì)算是否對下一個(gè)擴(kuò)展區(qū)發(fā)出異步預(yù)取請求。如果擴(kuò)展區(qū)順序讀取的頁面數(shù)大于或等于此參數(shù)則啟動(dòng)整個(gè)后續(xù)擴(kuò)展區(qū)的異步讀取操作。設(shè)值范圍為0-64之間,默認(rèn)為56,。值越高訪問檢查越嚴(yán)格。
  • 隨機(jī)預(yù)讀:根據(jù)緩沖池中已有的頁面來預(yù)測何時(shí)可能需要該頁面,而不管這些頁面的讀取順序如何。需要設(shè)置 innodb_random_read_ahead為on。

如果服務(wù)器資源利用率不高也可以通過調(diào)整Buffer Pool參數(shù)來提高資源利用率這里我們就大致說幾種(有興趣的話我們單獨(dú)開一篇說說mysql內(nèi)存怎么使用):

  • 增加緩沖池實(shí)例大小:在大內(nèi)存機(jī)器上調(diào)整 innodb_buffer_pool_instances來提高并發(fā)性。
  • 增加緩沖池大小:太小會(huì)造成數(shù)據(jù)攪動(dòng),太大會(huì)造成爭用內(nèi)存而導(dǎo)致交換。通常建議將 innodb_buffer_pool_size其配置為系統(tǒng)內(nèi)存的50%到75%。緩沖池大小必須始終等于innodb_buffer_pool_chunk_size* innodb_buffer_pool_instances的倍數(shù)否則Buffer Pool會(huì)自動(dòng)調(diào)整為此規(guī)則。
  • 調(diào)整刷盤函數(shù):在某些Linux/Unix版本的系統(tǒng)使用fsync()刷盤時(shí)性能異常差,存在這樣的問題可以使用innodb_flush_method參數(shù)設(shè)置為進(jìn)行基準(zhǔn)測試O_DSYNC。
  • noop調(diào)度或時(shí)間調(diào)度程序與本機(jī)AIO一起使用:innodb_use_native_aio(關(guān)于系統(tǒng)調(diào)度程序請參考本文尾部資料:調(diào)整 Linux I/O 調(diào)度器優(yōu)化系統(tǒng)性能)
  • 配置緩沖池刷新:緩沖池刷新是由頁面清理程序線程執(zhí)行的。清理程序線程的數(shù)量由innodb_page_cleaners變量控制默認(rèn)4。 當(dāng)臟頁百分比達(dá)到innodb_max_dirty_pages_pct_lwm變量定義的低水位標(biāo)記值時(shí),啟動(dòng)緩沖池刷新。默認(rèn)低水位為0,這會(huì)禁用早期的刷新。 盡量提高臟頁刷盤的利用率。還有innodb_flush_neighbors參數(shù)是指:從緩沖池刷新頁面是否也刷新其他臟頁面,0為不刷新,默認(rèn)為1刷新與其連續(xù)的臟頁,2為刷新相同extend上的臟頁。
  • 配置innodb_lru_scan_depth參數(shù):針對每個(gè)緩沖池實(shí)例指定頁面清理線程掃描以查找要刷新的臟頁面的緩沖池LRU列表的下行距離。

我們可以通過SHOW ENGINE INNODB STATUS來查看Buffer Pool的狀態(tài):

---------------------- BUFFER POOL AND MEMORY ---------------------- Total large memory allocated 2198863872 Dictionary memory allocated 776332 Buffer pool size 131072 Free buffers 124908 Database pages 5720 Old database pages 2071 Modified db pages 910 Pending reads 0 Pending writes: LRU 0, flush list 0, single page 0 Pages made young 4, not young 0 0.10 youngs/s, 0.00 non-youngs/s Pages read 197, created 5523, written 5060 0.00 reads/s, 190.89 creates/s, 244.94 writes/s Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000 Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s LRU len: 5720, unzip_LRU len: 0 I/O sum[0]:cur[0], unzip sum[0]:cur[0]提示:基于InnoDB上次打印輸出以來經(jīng)過的時(shí)間每秒平均值

Change Buffer

僅非主鍵索引的二級索引頁不在Buffer Pool中時(shí),會(huì)更改這部分緩存,將合并后讀入Buffer Pool再刷到磁盤。先來看個(gè)圖吧:

非主鍵索引中的插入順序相對隨機(jī),刪除和修改可能會(huì)影響不相鄰的非主鍵索引頁,最后通過異步線程將受影響的頁讀入Buffer Pool時(shí)批量合并更改并寫入磁盤,這將減少每次更改讀取IO的消耗。(如果索引包含降序索引列或主鍵包含降序索引列,則非主鍵索引不會(huì)進(jìn)Change Buffer)。通常情況下當(dāng)我們在表上操作Insert時(shí)非主鍵索引列的值通常都是未排序的,需要大量IO保證最新狀態(tài)。引入Change Buffer后 非主鍵索引的更改將進(jìn)入其中,而不是立即刷新到磁盤。當(dāng)頁面加載到Buffer Pool時(shí)會(huì)合并更改然后刷盤(適合大量的MDL操作:批量插入等)。當(dāng)然對于合并率較低的庫庫表操作我們可以通過參數(shù)innodb_change_buffering選擇關(guān)閉或者調(diào)整Change Buffer來提升性能。它的設(shè)值有以下幾種:

  • all:默認(rèn)值:緩沖區(qū)插入,刪除標(biāo)記操作和清除。
  • none:關(guān)閉緩沖任何操作。
  • inserts:緩沖區(qū)插入操作。
  • deletes:緩沖區(qū)刪除標(biāo)記操作。
  • changes:緩沖插入和刪除標(biāo)記操作。
  • purges:緩沖在后臺(tái)發(fā)生的物理刪除操作。

當(dāng)然根據(jù)庫表的使用情況,通過innodb_change_buffer_max_size來設(shè)置Change Buffer總大小的百分比,默認(rèn)25,最大50。 當(dāng)有大量寫入的操作時(shí)還可以調(diào)整innodb_change_buffer_max_size,否則就出現(xiàn)合并更改跟不上新產(chǎn)生的的條目,從而導(dǎo)致Change Buffer內(nèi)存達(dá)到上限。(可以根據(jù)實(shí)際情況動(dòng)態(tài)設(shè)置)我們可以通過如下命名查看Change Buffer的狀態(tài):

mysql> SHOW ENGINE INNODB STATUSG

Change Buffer狀態(tài)位于INSERT BUFFER AND ADAPTIVE HASH INDEX 標(biāo)題下,內(nèi)容大致如下

------------------------------------- INSERT BUFFER AND? ADAPTIVE HASH INDEX ------------------------------------- Ibuf: size 1, free list len 0, seg size 2, 0 merges merged operations:insert 0, delete mark 0, delete 0 discarded operations:insert 0, delete mark 0, delete 0 Hash table size 4425293, used cells 32, node heap has 1 buffer(s) 13577.57 hash searches/s, 202.47 non-hash searches/s

Log Buffer

保存要寫入磁盤上的日志文件的數(shù)據(jù)。日志緩沖區(qū)大小由innodb_log_buffer_size變量定義 。默認(rèn)大小為16MB。Log Buffer的內(nèi)容會(huì)定期刷新到磁盤。較大的日志緩沖區(qū)使大型事務(wù)可以運(yùn)行,而無需在事務(wù)提交之前將redo log數(shù)據(jù)寫入磁盤。如果您有很多行的寫事務(wù),則增加Log Buffer的大小可以節(jié)省磁盤的IO開銷。innodb_flush_log_at_trx_commit 變量控制如何將Log Buffer區(qū)的內(nèi)容寫入并刷新到磁盤。該 innodb_flush_log_at_timeout 變量控制日志刷新頻率。

Adaptive Hash Index

該功能可以在InnoDB不犧牲事務(wù)功能或可靠性的情況下,在工作線程Buffer Pool有足夠內(nèi)存的的系統(tǒng)上充當(dāng)內(nèi)存數(shù)據(jù)庫使用,使用innodb_adaptive_hash_index 變量啟用。 自適應(yīng)哈希索引是根據(jù)觀察者模式查找由索引關(guān)鍵字前綴構(gòu)建的哈希索引,該前綴可以是任何長度,可以是Hash Tree索引中僅B Tree中的某些值出現(xiàn)。它是根據(jù)經(jīng)常訪問的索引頁的需求而建立的 ,模糊查找與范圍查找不適用,在并發(fā)情況下回造成資源爭搶。由于很難預(yù)先預(yù)測自適應(yīng)哈希索引功能是否適合特定的系統(tǒng)和工作負(fù)載,因此請考慮啟用和禁用該功能的基準(zhǔn)測試。

參考閱讀資料:

  • 調(diào)整 Linux I/O 調(diào)度器優(yōu)化系統(tǒng)性能:https://www.ibm.com/developerworks/cn/linux/l-lo-io-scheduler-optimize-performance/index.html
  • Benefits of Using InnoDB Tables :https://dev.mysql.com/doc/refman/5.7/en/innodb-benefits.html

總結(jié)

以上是生活随笔為你收集整理的禁用内存清理_MySql那些事儿(二):InnoDB架构介绍之内存篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。