從Purge機制說起,詳解GaussDB(for MySQL)的優化策略

来源:https://www.cnblogs.com/huaweiyun/p/18251951
-Advertisement-
Play Games

當前GaussDB(for MySQL)的Purge優化功能,通過任務流水線化、線程優先順序調整、二次分發等手段,避免資料庫undo log堆積,極大提升Purge的性能,大幅改善用戶體驗。 ...


本文分享自華為雲社區《【華為雲MySQL技術專欄】GaussDB(for MySQL) Purge優化》,作者:GaussDB 資料庫。

在MySQL中,尤其是在使用InnoDB引擎時,Purge機制至關重要。它可以回收undo log【1】,清理過期數據,減少磁碟占用,維護資料庫的整潔與高效。

Purge機制

MySQL InnoDB引擎使用undo log來保存事務修改記錄的歷史信息。事務提交後, update undo log(指在delete和update操作中產生的回滾日誌)未被立即刪除,而是會被記錄到undo history list【2】,等待Purge線程進行最後的刪除。當undo log不再被任何事務依賴時,系統就會掃描這個undo log,將過期的索引數據刪除並清理undo log本身,這個整體的清理過程就是MySQL InnoDB引擎的Purge機制。

Purge的操作可以分成三個主要步驟:  

1.遍歷已經提交的update undo log

根據undo log header中的信息判斷這些事務是否存在過期數據,如果判斷存在過期數據,就要觸發Purge機制進行清理,否則就不需要。

2.通過undo log進行數據的物理刪除

其過程主要包括:掃描undo 頁面來獲取undo記錄,遍歷undo記錄以確認是否要進行清理,如果需要則刪除索引中的過期數據。

3.回收undo log

purge的速度會影響已提交的undo log的清理回收,如果purge的清理速度趕不上事務生成undo log的速度,undo log就會出現堆積。如果條件允許的話,對undo tablespace進行truncate(截斷)來實現undo空間的回收。

undo log堆積主要會產生兩方面的影響:

第一, 額外的存儲占用

undo log和索引都有歷史版本數據,undo log未及時清理會導致undo log自身以及undo關聯的過期索引數據產生堆積,占用額外的存儲空間,容易引起不必要的擴容和開銷,對客戶業務而言是不利的。

第二,性能下降

undo log堆積會導致過期索引數據堆積,索引頁面中會存在大量已經標記為delete的數據,這時候每個索引頁面實際的有效數據占比就會很低,業務SQL執行中會出現獲取少量數據卻需要進行大量頁面IO的情況,最終導致SQL執行性能劣化。

Purge優化實現

當前undo堆積已經成為資料庫運行的一個痛點問題,因此華為雲GaussDB(for MySQL)團隊專門針對Purge機制存在的問題進行瞭如下優化。

優化點一:coordinator 與 worker流水線化

Purge任務是由Purge線程完成的,是InnoDB的常駐線程。其線程主要分成兩個角色,分別是一個purge coordinator線程和若幹個purge worker線程,以下簡稱為coordinator和worker。

事務的修改可能會殘留過期數據在索引中,而老數據的相關信息又存留在undo記錄中,事務提交時的undo log會被記錄在回滾段的History List中,coordinator負責從History List中獲取undo log,讀取其中的undo記錄,並將可能殘留過期數據的undo記錄分發給worker來進行處理。所以,當前purge的流程可以簡單劃分成以下兩個階段:

階段一:coordinator讀取undo log包含的undo頁面,獲取undo記錄。

階段二:coordinator將讀取到的undo記錄批量分發給worker來進行處理,線程之間併發執行,且coordinator也會負責一部分undo記錄的處理,待coordinator和所有worker都執行完畢後開啟下一輪處理。

1.png

圖1 purge原生流程

圖1所示為原本的Purge流程,階段一coordinator是單線程執行,階段二worker是多線程併發,即並行執行,但整體兩個階段是串列執行,即階段一執行完,階段二才會繼續執行。如果階段一存在大量undo 頁面都需要進行IO,串列執行就會嚴重影響整體的執行效率。不過,這種兩階段串列化執行的方式是可以優化的。

優化的整體思想即是:將coordinator和worker的執行流水線化。從圖1可以看到,在原生Purge流程中,coordinator除了負責掃描獲取undo記錄的任務,本身也會承擔一部分Purge任務,且必須同步等待所有已分發的Purge任務完成之後,才能開始下一批次的undo記錄掃描任務,這樣就導致階段一和階段二是一個串列過程。

若令coordinator只單一地負責undo記錄的掃描,不再兼職Purge清理任務,這樣在worker執行的過程中,coordinator就能直接繼續去獲取undo記錄, 不再需要同步等待所有的Purge任務完成,這樣就可以達到將原本串列的兩階段執行變成流水線執行的目的。

2.png

圖2 purge優化流程

圖2為優化後的Purge流程,Purge優化會先將innodb_purge_batch_size指定的undo頁面拆成若幹個小的batch, 拆分的批次數量由innodb_rds_purge_subbatch_size決定。coodinator會先掃描第一個小batch的undo 記錄,然後分發給各個worker並行處理,在worker處理過程中,coordinator可以去掃描第二個小batch的undo記錄,等到所有worker執行完第一批purge任務後,coordinator將立即分發第二批undo記錄,worker繼續並行執行,而coordinator則立即開始並行地解析第三個小batch的undo記錄,以此類推。

  • 優化效果評估

當coordinator獲取完第一個小batch之後,後續coordinator和worker都是同時運行的,每個batch運行的時間由coordinator和worker運行時間較長者決定,為了避免不必要的線程間等待,需要通過調整參數來令兩個線程的耗時接近。

目前通過開啟innodb_monitor_enable的module_purge監控,觀察coordinator的耗時以及worker的耗時,再通過調整innodb_purge_batch_size和innodb_rds_purge_subbatch_size參數,將coordinator和worker的耗時調整到接近,讓每個batch整體耗時降低。當前測試結果,innodb_purge_batch_size(600),innodb_rds_purge_subbatch_size(150)為最優配置,在此配置下purge速度有1倍提升。

優化點二:undo記錄二次分發

我們發現當前在Purge過程中,coordinator分發undo記錄給worker的策略是基於InnoDB層的table id,即對於同一個表的undo記錄都會分發給一個worker。

這就會出現一種場景:當單個熱點表被頻繁執行DML時,會生成大量基於這個表的undo記錄,此時無論innodb_purge_threads值設置多大,Purge的任務都只會由一個線程承擔,Purge機制由原本設計上的併發執行回退成單線程執行,Purge效率降低。

針對這個問題,我們在保持基於table id分發邏輯的基礎上,增加一輪二次分發機制。

  • 整體思路

01 根據Purge線程數將undo記錄進行分組(如圖3),Purge線程數量為4,因此將undo記錄劃分為四個分組。

02 第一次分發(基於table id分發):將獲取出來的undo記錄根據table id進行分配,如果當前分組已存在該table id對應的undo記錄,則繼續分配至該分組;如果不存在包含該table_id的undo記錄的分組,則尋找一個容量最小的分組,然後分配給小容量分組。

03 檢測當前分配是否均衡,確認當前是否每個分組的記錄數都小於max_n= (m_total_rec + n_purge_threads - 1) / n_purge_threads。

如果是大於max_n則說明當前分組過載,否則就認為是均衡的。如圖3中,max_n = (11+4 - 1) / 4 = 3,因此第二個、第四個分組均過載,需要進行二次分發。

04 第二次分發(基於分組負載分發):如果當前分組過載,則將過載部分數據轉移至相鄰下一個分組,然後校驗下一個分組是否過載,迴圈校驗,最多遍歷2次所有分組。圖4中,最終每個分組的記錄數不超過3條,相同table id的undo記錄也會分發到不同分組,例如rec3和rec4屬於相同的table,經過二次分發最終會分發到不同的分組,但是分發到不同分組對應最後的Purge結果並不影響。

3.png圖3 二次分發

4.png

圖4 最終分髮結果

優化點三:Purge線程優先順序調整

考慮到Purge相關的線程均為後臺常駐線程,對於GaussDB(for MySQL)而言,有較多後臺線程,因此本身Purge相關線程的調度不處於高優先順序,Purge線程不會被系統頻繁調度。所以,第三個優化點是調整Purge相關線程的優先順序,GaussDB(for MySQL)將以高優先順序啟動Purge線程,確保Purge任務能夠及時被調度。

測試驗證

預備條件

innodb_rds_fast_purge_enabled: 以上三個優化開啟的特性開關,開啟後特性全部生效。

innodb_purge_batch_size :單個大batch處理的undo頁面數,設置為600,一個大batch會被劃分成多個小batch。

innodb_rds_purge_subbatch_size:單個小batch處理的undo頁面數,設置為150。

測試模型一:驗證空載場景下Purge速度

  • 實例規格:8U32G

  • 資料庫版本:GaussDB(for MySQL)-2.0.51.240300

  • 操作系統:EulerOS 2.0(SPS)

  • 數據量:64 張sysbench寬表,單表1000萬行數據

  • 併發數: 1/4/8/16/32/64/128/256/512 線程併發,讀寫模型

  • 數據文件 :為了精確對比purge速度提升效果,我們對比空載場景即無業務負載。使用history length已經達到5億的數據文件,在空載場景下對比開啟優化和未開啟優化的清理速度。

實際開啟優化後,空載Purge清理速度大約有1倍提升,具體結果展示如下:

5.png

圖5 purge速度對比

測試模型二:驗證特性開啟後對SQL執行性能的影響

  • 實例規格:8U32G

  • 資料庫版本:GaussDB(for MySQL)-2.0.51.240300

  • 操作系統:EulerOS 2.0(SPS)

  • 數據量:64 張sysbench寬表,單表1000萬行數據

  • 併發數: 1/4/8/16/32/64/128/256/512 線程併發,讀寫模型

開啟和關閉開關後,執行sysbench不同併發下的性能表現如下,開啟關閉優化特性後,QPS基本持平,說明優化特性對於業務性能基本可以忽略。

6.png

圖6 性能對比

總結

Purge機制負責GaussDB(for MySQL) InnoDB過期數據的清理,對於資料庫高性能平穩運行起到至關重要的作用。Purge機制不及時不僅會導致過期數據的堆積,占用大量磁碟空間,還會影響SQL執行效率。當前GaussDB(for MySQL)的Purge優化功能,通過任務流水線化、線程優先順序調整、二次分發等手段,避免資料庫undo log堆積,極大提升Purge的性能,大幅改善用戶體驗。

相關概念

【1】Undo Log:即回滾日誌,保存了記錄修改前的數據。在InnoDB存儲引擎中,undo log分為insert undo log和update undo log。

insert undo log是指在insert操作中產生的undo log。由於insert操作的記錄,只是對本事務可見,其它事務不可見,所以undo log可以在事務提交後直接刪除,而不需要額外操作。

update undo log是指在delete和update操作中產生的undo log。該undo log可能要用於多版本併發控制的老版本數據獲取,因此不能在提交的時候刪除。

【2】Undo History List:即記錄所有已提交事務的undo log的鏈表,可以通過該鏈表找到所有未被清理的已提交事務關聯的undo log。事務提交時,insert undo log會被回收掉(reused或者free), update undo log則會被移動到Undo History List鏈表。因此Undo History List的長度即History Length反應了未被處理和回收的update undo log的數量,我們一般通過History Length來評估undo log堆積的情況,可以通過 show engine innodb status實時獲取這個值。

 

點擊關註,第一時間瞭解華為雲新鮮技術~

 


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

-Advertisement-
Play Games
更多相關文章
  • 如果把shell命令比成蓋房子的磚瓦,那shell腳本就是用一塊塊磚瓦建起來的房子。 腳本的第一行必須寫成類似下麵這樣的形式: #!/bin/bash #指定解釋器,其他還有dash,Python 等 變數 1.變數定義,賦值,引用 變數由字母和數字組成,值由雙引號包含,賦值號的兩邊不能有空格,例: ...
  • 目錄makefile 定義變數的方式1.遞歸定義2 直接定義3 條件定義方式4 追加變數值5 引用並修改變數值6 overrideVPATH用法:1 VPATH vpath各種規則1.隱式規則(Implicit Rules)2.靜態規則(Static Pattern Rules)3. 多目標規則(M ...
  • 瞭解更多關於bootloader 的C語言實現,請加我Q扣: 1273623966 (驗證信息請填 bootloader),歡迎咨詢或定製bootloader(線上升級程式)。 不知道為什麼,現在工業控制領域也向汽車領域學習,產品需要帶bootloader, 產品出貨後也要可以通過bootloade ...
  • 虛擬機添加磁碟與linux邏輯捲擴容 1.1 虛擬機添加磁碟 1.1.1. 檢查linux系統的磁碟分區及邏輯捲的相關信息是否正常 (1)cat /etc/redhat-release查看系統版本【適用於RHEL及CentOS】: 我已自己電腦上的虛擬機,50G記憶體2G運行記憶體為例 >>> (2)d ...
  • nslookup 是一個網路診斷工具,用於查詢功能變數名稱系統(DNS)記錄,將功能變數名稱解析為IP地址,或者查詢其他DNS記錄類型,如MX(郵件交換記錄)、CNAME(別名記錄)等。以下是一些常見Linux發行版安裝 及使用nslookup 的方法: Debian/Ubuntu 及其衍生版安裝 使用 apt 包 ...
  • 在學習Hadoop工具中的Flume時,有的小伙伴會遇到這句話: “Flume要想將數據輸出到HDFS,必須持有Hadoop相關jar包” 然後小伙伴就懵逼了,這些包要去什麼地方來找呢? (遠在天邊,近在眼前) 首先,我們需要的包有 commons-configuration-1.6.jar、 ha ...
  • 概述 explain 關鍵字可以模擬執行 sql 查詢語句,輸出執行計劃,分析查詢語句的執行性能 使用方式如下:explain + sql explain select * from t1 執行計劃各欄位含義 1. id 如果 id 序號相同,從上往下執行 如果 id 序號不同,序號大先執行 如果兩 ...
  • 在 MySQL 中,如果我們想查看實例當前正在執行的 SQL,常用的命令是SHOW PROCESSLIST。 但如果 SQL 過長的話,就會被截斷。這時,我們一般會用SHOW FULL PROCESSLIST來查看完整的 SQL。 最近碰到一個 case,發現無論是使用 SHOW PROCESSLI ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...