MySQL 筆記整理(12) --為什麼我的MySQL會“抖”一下?

来源:https://www.cnblogs.com/dogtwo0214/archive/2019/03/27/10595034.html
-Advertisement-
Play Games

筆記記錄自林曉斌(丁奇)老師的《MySQL實戰45講》 (本篇內圖片均來自丁奇老師的講解,如有侵權,請聯繫我刪除) 12) --為什麼我的MySQL會“抖”一下? 斷更了一段時間,因為這幾周實在是太忙了,周末加班兩天那種。。。 有時你會遇到這樣的問題,一條SQL語句,正常執行的時候很快,但是有時候會 ...


筆記記錄自林曉斌(丁奇)老師的《MySQL實戰45講》

(本篇內圖片均來自丁奇老師的講解,如有侵權,請聯繫我刪除)

12) --為什麼我的MySQL會“抖”一下?

  斷更了一段時間,因為這幾周實在是太忙了,周末加班兩天那種。。。

  有時你會遇到這樣的問題,一條SQL語句,正常執行的時候很快,但是有時候會變得特別慢。並且這種場景很難復現,不只隨機而且持續時間很短。這其實與MySQL的臟頁以及它的刷新機制有關。之前我們有過一個關於《孔乙己》裡面酒館老闆記賬的比喻。在這個比喻里,掌柜的賬本就是我們的數據文件,掌柜的臨時寫下的粉板就是我們的日誌文件(redo log),而掌柜的記憶就相當於我們的記憶體。

  粉板可以記錄的內容有限(redo log迴圈寫),掌柜的記憶也是有限的,因此他總要找時間把這兩部分的內容記錄到賬本里去。這個術語就是flush.

  當記憶體數據頁跟磁碟數據頁內容不一致的時候,我們稱這個記憶體頁為“臟頁”。記憶體數據寫入到磁碟後,記憶體和磁碟上的數據頁的內容就一致了,稱為“乾凈頁”。

  大致上有四種情景來進行刷“臟頁”:

  1. 粉板滿了。(redo log寫滿),redo log寫滿以後,如果又有了新的數據,就不得不去除一些之前的數據。當然,在去除之前,要先把正確的數據記錄下來才行。
  2. 生意太好,短時間內有很多客人,掌柜的記不下來了。(系統記憶體不足)。記憶體不足時,需要先淘汰掉一些數據頁,如果這些數據頁中有“臟頁”就必須要把這些記錄到磁碟才行。你可能會有疑問,為什麼不直接淘汰掉這些頁呢,如果再有相關的記錄,就利用redo log來還原數據呢?(掌柜的疑問一部分腦子裡的記憶,下次再有的話,先看賬本,然後再看粉板,倒退出最新的記錄),這其實是從性能方面考慮的。如果我們保證每次刷臟頁一定會寫磁碟,那麼下次再讀的時候就有兩種情況。一是記憶體中有記錄,那麼直接返回。二是,記憶體中沒有,那麼先從磁碟讀,讀到了就直接返回。對應掌柜的就是,掌柜的有印象,直接返回。掌柜的沒有印象查看賬本,找到了就直接返回。
  3. 生意不太忙的時候,掌柜的閑著沒事,就更新賬本。(系統空閑),閑著沒事,Mysql就自己刷臟頁玩。
  4. 年底放假,酒店關門幾天。(MySQL正常關閉),正常關閉時MySQL會把記憶體的臟頁都flush到磁碟上。

  回到我們開始的問題,什麼情況會抖一下呢?首先排除後兩種,空閑或是要關閉資料庫時。來看看前兩種情況:

  先是redo log寫滿了,要flush臟頁,這種情況是InnoDB要儘量避免的。因為這種情況下,整個系統就不能再接受更新了,所有的更新都必須堵住。如果你從監控上看,這時的更新數會跌為0.然後是第二種情況:“記憶體不夠用了,要先將臟頁寫到磁碟”。這種情況是常態。InnoDB用緩衝池(buffer pool)管理記憶體,緩衝池中的記憶體頁有三種狀態:

  1. 還沒使用的
  2. 使用了並且是乾凈頁的
  3. 使用了並且是臟頁的  

  InnoDB的策略是儘量使用記憶體,因此對於一個長時間運行的庫來說,未被使用的頁面很少。當要讀入的數據頁沒有在記憶體的時候,就必須到緩衝池中申請一個數據頁。這時候只能把最久不使用的數據頁從記憶體中淘汰掉。如果淘汰掉的是一個乾凈頁,可以直接釋放出來複用。如果淘汰掉的是一個臟頁,就必須先將臟頁刷到磁碟,變成乾凈頁後才能復用。所以,刷臟頁雖然是常態,但是出現以下兩種情況,都會明顯的影響性能:

  1. 一個查詢要淘汰的臟頁太多,會導致查詢的響應時間明顯變長
  2. 日誌寫滿,更新全部堵住,寫性能跌為0,這個情況對敏感業務來說,是不能接受的。

  所以,InnoDB需要有控制臟頁比例的機制,來儘量避免上面的這兩種情況。

InnoDB刷臟頁的控制策略

  首先,你要正確地告訴InnoDB所在主機的IO能力,這樣InnoDB才能知道需要全力刷臟頁的時候,可以刷多快。這個就要用到innodb_io_capacity這個參數了,它會告訴InnoDB你的磁碟能力。這個值建議你設置為磁碟的IOPS,磁碟的IOPS可以通過fio(linux)來進行測試。(Linux下fio,window下可以使用iometer)

  InnoDB使用兩個因素來進行計算刷盤速度。一個是臟頁比例,一個是redo log的寫盤速度。參數innodb_max_dirty_pages_pct是臟頁比例上限,預設值是75%。InnoDB會根據當前的臟頁比例M,算出一個範圍在0到100之間的數字。InnoDB每次寫入日誌都有一個序號,當前寫入的序號跟checkpoint對應的序號之間的差值,我們假設為N,同樣,InnoDB會根據這個N算出一個0到100之間的數字。N越大這個計算出來的值就越大。然後,根據上述兩個計算出的數據f(M)和f(N),取其中較大的值記為R,之後引擎就可以按照innodb_io_capacity定義的能力乘以R%來控制刷臟頁的速度了。

  因此要合理的設置innodb_io_capacity的值,平時要多關註臟頁的比例,不要讓它經常接近75%。

  還有一個有趣的策略:一旦一個請求涉及到刷臟頁,在準備進行刷臟頁的時候,會把這個數據頁旁邊的數據頁也檢查一下,如果這個鄰居也是臟頁,那麼就會把鄰居一起刷掉。InnoDB使用參數innodb_flush_neighbors參數來控制這個行為,為1的時候就會觸發這個“連坐”機制。在MySQL8.0中,這個預設值已經是0了。

上期問題:

  如果你要維護學生信息的資料庫,學生登錄名統一是"學號@gamail.com",學號的規則是十五位的數字,前三位是城市編號,四到六位是學校編號,七到十位是入學年份,最後五位是順序編號,只考慮登錄驗證的話,你會怎麼設計這個登錄名的索引呢?

  由於這個學號的規則,無論是正向還是反向的首碼索引,重覆度都很高。前三位是城市編號,四到六位是學校編號,這六位數字其實是相對固定的。而郵箱尾碼也是確定的,因此可以只存入學年份加順序編號,它們的長度是9位。在此基礎上,可以用數字類型來存儲這個9位數字,這樣只需占用4個位元組,這其實是一種hash,只是用了最簡單的轉換規則。

  另有別的思路是,一個學校總人數不會很大,這點數據量,這個表必然是個小表。直接存原來的字元串,可以使業務更簡單。這也是一種很好的回答,結合實際業務。

問題:

  一個記憶體配置為128GB,innodb_io_capacity設置為20000的大規格實例,正常會建議你將redo log設置成4個1GB的文件,但是如果你配置時不小心將redo log設置為了4個100M的文件,會發生什麼情況呢?為什麼呢?


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 博客為日常工作學習積累總結: 環境準備: 系統安裝完成後: 1.配置靜態IP 網卡文件:cat /etc/sysconfig/network-scripts/ifcfg-eth0 配置靜態IP代碼如下 重啟網卡: service network restart systemctl restart n ...
  • 硬體環境 ubuntu 16.04LTS + windows10 雙系統 NVIDIA TiTan XP 顯卡(12G) 軟體環境 搜狗輸入法 顯卡驅動:LINUX X64 (AMD64/EM64T) DISPLAY DRIVER (418.56) https://www.nvidia.cn/Dow ...
  • socket socket也稱套接字,網路編程的基礎。一般情況下我不喜歡直接去說socket的函數都是怎麼用的,那個很多人都寫出來了,而且肯定比我好的有的是。 但是今天想寫的是我的理解中,產生socket的原因,我覺得只有瞭解socket的本質、機理,才能更靈活的使用他的API。那樣就會知道為什麼要 ...
  • Linux指令 useradd + 添加用戶 + d 添加用戶路徑 + e 制定密碼有效時間 + G 指定用戶所屬組 passwd + 修改用戶密碼 su + 切換用戶 exit + 退出連接(ssh連接,screen) touch + 新建一個文件 mkdir + 新建一個文件夾 ls + 顯示當 ...
  • mysql 回顧 資料庫的設計必須滿足三範式 1NF: 強調列的原子性,列不可拆分 eg: 一張表(聯繫人) 有(姓名,性別,電話)三列,但是現實中電話又可分為家庭電話和公司電話,這種表結構設計就不符合第一範式了, 正確的應該是繼續拆分(姓名,性別,家庭電話,公司電話) 2NF: 首先滿足1NF,另 ...
  • Linux Mysql資料庫安全配置 目錄: 1.修改mysql管理員賬號root的密碼(2種方法) 2.修改mysql管理員賬號root 3.mysql管理員root賬號密碼遺忘解決辦法(2種方法) 4.創建資料庫用戶(3種方法) 5.mysql資料庫許可權管理 本地許可權 網路許可權 撤銷許可權 刪除用 ...
  • Redis Cluster採用虛擬槽分區,所有的key根據哈希函數映射到0~16383槽內,計算公式: slot = CRC16(key) & 16383 每個節點負責維護一部分槽以及槽所映射的鍵值對。 Redis虛擬槽分區的特點,解耦數據與節點之間的關係,簡化了節點擴容和收縮難度。但其存在如下限制 ...
  • 1.hive概述 Apache Hive數據倉庫軟體有助於使用SQL讀取,編寫和管理駐留在分散式存儲中的大型數據集。可以將結構投影到已存儲的數據中。提供了命令行工具和JDBC驅動以將用戶連接到Hive。 2.hive優缺點 優點: (1)操作介面採用了sql,簡化開發,減少學習成本。 (2)避免手寫 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...