Mysql - 臟頁

1 . 臟頁(內(nèi)存頁)

當內(nèi)存數(shù)據(jù)頁跟磁盤數(shù)據(jù)頁內(nèi)容不一致的時候,我們稱這個內(nèi)存頁為“臟頁”。內(nèi)存數(shù)據(jù)寫入到磁盤后,內(nèi)存和磁盤上的數(shù)據(jù)頁的內(nèi)容就一致了,稱為“干凈頁”。

不論是臟頁還是干凈頁,都在內(nèi)存中。

平時很快的更新操作,都是在寫內(nèi)存和日志。

一條 SQL 語句,正常執(zhí)行的時候特別快,但是有時也不知道怎么回事,它就會變得特別慢。

那這時候可能就是在刷臟頁到磁盤中了~ flush

2 . 什么時候會引起flush?

(1) InnoDB的redo log寫滿了。這時候系統(tǒng)會停止所有的更新操作,然后讓日志可以繼續(xù)寫。

把這部分數(shù)據(jù)日志都flush到磁盤上面。

(2) 也可能是系統(tǒng)內(nèi)存不足,需要新的內(nèi)存頁,那么就淘汰一些內(nèi)存頁,空出來的給別的數(shù)據(jù)頁使用。

先把臟頁寫到磁盤。

PS:使用內(nèi)存是為了效率更好,

因為如果內(nèi)存存在數(shù)據(jù)頁,那么數(shù)據(jù)就一定正確,直接返回;

如果內(nèi)存沒有數(shù)據(jù),才需要去磁盤中取,讀入到內(nèi)存,返回;

(3) MySQL 認為系統(tǒng)“空閑”的時候,反正閑著也是閑著hh

反正有機會就刷點數(shù)據(jù)

(4)MySQL 正常關閉。這時候,MySQL 會把內(nèi)存的臟頁都 flush 到磁盤上,這樣下次 MySQL 啟動的時候,就可以直接從磁盤上讀數(shù)據(jù),啟動速度會很快。

3 . 影響

3.1 如果是redo log寫滿了
盡量避免的。因為出現(xiàn)這種情況的時候,整個系統(tǒng)就不能再接受更新了,所有的更新都必須堵住。更新數(shù)為 0。

3.2 內(nèi)存不夠用了
常態(tài),很正常。

3.3 buffer pool
因為innodb用的是buffer pool 管理內(nèi)存,緩沖池中的內(nèi)存頁有三種狀態(tài):第一種是還沒有使用的;第二種是使用了并且是干凈頁;第三種是使用了并且是臟頁。

Innodb 的內(nèi)存策略是盡量使用內(nèi)存。

4 . Innodb 刷臟頁的控制策略

我覺得知道一下就好,這個臟頁刷的快不快跟磁盤的能力有關。

可以通過innodb_io_capacity 這個參數(shù)設置磁盤能力。

InnoDB 的刷盤速度就是要參考這兩個因素:一個是臟頁比例,一個是 redo log 寫盤速度。

平時要多關注臟頁比例,不要讓它經(jīng)常接近 75%。

INNODB刷臟頁,如果發(fā)現(xiàn)旁邊也是臟頁,那么會連帶著一起刷掉。

所以可能會很慢,如果你的查詢正好要先flush一個臟頁的話。

在 InnoDB 中,innodb_flush_neighbors 參數(shù)就是用來控制這個行為的,值為 1 的時候會有上述的“連坐”機制,值為 0 時表示不找鄰居,自己刷自己的。

找“鄰居”這個優(yōu)化在機械硬盤時代是很有意義的,可以減少很多隨機 IO。機械硬盤的隨機 IOPS 一般只有幾百。

但是SSD 的IO很高,所以可以不用非要有刷寫鄰居的操作,可以加快響應。

在 MySQL 8.0 中,innodb_flush_neighbors 參數(shù)的默認值已經(jīng)是 0 了。

5 . QA

  • Q:怎么知道一個也是不是臟頁?
    內(nèi)存中每個數(shù)據(jù)頁頭部有LSN,8字節(jié),每次修改都會變大。

對比這個LSN跟checkpoint 的LSN,比checkpoint小的一定是干凈頁

也就是如果內(nèi)存中比redolog的頭部小,那么就是干凈頁

  • Q:LSN?
    Log sequence number: 當前系統(tǒng)最大的LSN號

每個數(shù)據(jù)頁有LSN,重做日志有LSN,checkpoint有LSN。

占用8字節(jié),LSN主要用于發(fā)生crash時對數(shù)據(jù)進行recovery,LSN是一個一直遞增的整型數(shù)字,表示事務寫入到日志的字節(jié)總量。
LSN不僅只存在于重做日志中,在每個數(shù)據(jù)頁頭部也會有對應的LSN號,該LSN記錄當前頁最后一次修改的LSN號,用于在recovery時對比重做日志LSN號決定是否對該頁進行恢復數(shù)據(jù)。前面說的checkpoint也是有LSN號記錄的,LSN號串聯(lián)起一個事務開始到恢復的過程。

感謝:https://www.cnblogs.com/drizzle-xu/p/9713378.html

我感覺就是可以理解為是一個long類型的數(shù)字,可以根據(jù)這個來比較要不要刷寫數(shù)據(jù),以及是不是干凈頁面,在恢復數(shù)據(jù)要拿這個進行比較。

緩存區(qū)域,緩存數(shù)據(jù)和索引在內(nèi)存中。

innodb使用了一些鏈表。
lru鏈表:用來存儲內(nèi)存中的緩存數(shù)據(jù)。
free鏈表:用來存放所有的空閑頁,每次需要數(shù)據(jù)頁存儲數(shù)據(jù)時,就首先檢測free中有沒有空閑的頁來分配。
flush鏈表:在內(nèi)存中被修改但還沒有刷新到磁盤的數(shù)據(jù)頁列表,就是所謂的臟頁列表,內(nèi)存中的數(shù)據(jù)跟對應的磁盤上的數(shù)據(jù)不一致,屬于該列表的頁面同樣存在于lru列表中,但反之未必。

  • Q:刷寫的答題過程?
    buffer pool里維護著一個臟頁列表,假設現(xiàn)在redo log 的 checkpoint 記錄的 LSN 為 10,現(xiàn)在內(nèi)存中的一干凈頁有修改,修改后該頁的LSN為12,大于 checkpoint 的LSN,則在寫redo log的同時該頁也會被標記為臟頁記錄到臟頁列表中,現(xiàn)在內(nèi)存不足,該頁需要被淘汰掉,該頁會被刷到磁盤,磁盤中該頁的LSN為12,該頁也從臟頁列表中移除,現(xiàn)在redo log 需要往前推進checkpoint,到LSN為12的這條log時,發(fā)現(xiàn)內(nèi)存中的臟頁列表里沒有該頁,且磁盤上該頁的LSN也已經(jīng)為12,則該頁已刷臟,已為干凈頁,跳過。

將臟頁flush到磁盤上是直接將臟頁數(shù)據(jù)覆蓋到對應磁盤上的數(shù)據(jù)

  • Q: 很多測試人員再做壓力測試的時候寫入慢也跟redolog有關?
    出現(xiàn)剛開始 insert update 很快 一會 就出現(xiàn)很慢,并且延遲很大,大部分是因為redo log 設置太小 引起的

  • Q:如果系統(tǒng)性能差,為什么會慢?
    因為臟頁刷的很慢,堆積了之后,就會等待臟頁刷完之后在進行更新和讀取。
    ————————————————
    版權聲明:本文為CSDN博主「pmdream」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權協(xié)議,轉載請附上原文出處鏈接及本聲明。
    原文鏈接:https://blog.csdn.net/pmdream/article/details/103668933

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 什么是臟頁? InnoDB在處理更新語句時,先寫內(nèi)存再寫redo log,并不會立即將數(shù)據(jù)頁的更新落地到磁盤(WA...
    HYIndex閱讀 2,725評論 0 1
  • MySQL內(nèi)存結構-緩沖區(qū) MySQL的緩沖區(qū)中有數(shù)據(jù)頁,索引頁,插入緩沖等等,這個角度是從頁的功能來分類的。本小...
    ging_efcf閱讀 1,140評論 0 0
  • 當內(nèi)存數(shù)據(jù)頁跟磁盤數(shù)據(jù)頁內(nèi)容不一致的時候,我們稱這個內(nèi)存頁為“臟頁”。內(nèi)存數(shù)據(jù)寫入到磁盤后,內(nèi)存和磁盤上的數(shù)據(jù)頁的...
    wmtcore閱讀 1,146評論 0 0
  • redo日志是個啥 我們知道InnoDB存儲引擎是以頁為單位來管理存儲空間的,我們進行的增刪改查操作其實本質上都是...
    tracy_668閱讀 712評論 1 5
  • 回顧 上個文章我們了解了: InnoDB的在內(nèi)存中的緩沖池. 緩存淘汰算法midpoint insertion s...
    AbstractCulture閱讀 986評論 0 0

友情鏈接更多精彩內(nèi)容