MySQL 大事務提交優化

在使用和運維 MySQL 的過程中你一定碰到過下面這種奇怪的慢 SQL。

當這種情況出現時,最有可能的就是有大事務在提交。以下是一個模擬測試的結果,我們用 Sysbench 來模擬正常的業務,然後在後臺每 5 秒執行一個大的 UPDATE,可以看到大的 UPDATE 會嚴重的影響業務的性能。

根因分析

上圖展示了兩個事務的執行過程:

問題的嚴重性

從前面我們的模擬測試我們可以看到,大事務的提交對業務的穩定性是有非常大的影響的。實際的使用場景中可能要嚴重的多,並且也很普遍。

大事務寫 Binlog 優化

我們在 AliSQL 上對大事務寫 Binlog 的過程做了優化,徹底消除了大事務提交對穩定性的影響。RDS-5.7,RDS-8.0 都已經默認的開啓了這個優化。去年我們將 AliSQL 的這個優化捐贈給了 MariaDB,這個功能已經在 MariaDB-11.7[1] 上發佈。

優化方案

下面我來介紹一下 MariaDB-11.7 上的實現方案,MySQL 和 MariaDB 代碼上雖然差別已經比較大了,但是根本的邏輯還是一樣的,所以實現方案也是一樣的。

這個優化方案說起來是比較簡單和清晰的:既然 Binlog Cache 已經將 Binlog Events 寫到了文件裏,那我們就直接把這個文件直接轉成(rename)一個Binlog文件。這樣就不需要拷貝 Binlog Events,沒有額外的 IO 產生。並且 Rename 操作的時間是恆定的和 Binlog Cache 的大小無關,可以徹底解決大事務造成的問題。下面我們來看一下實現邏輯。

#binlog_cache_files 目錄

Binlog Cache 裏的文件是一個系統臨時文件,不能直接轉成一個普通文件。因此我們在 binlog 所在的目錄創建了一個目錄#binlog_cache_files,Binlog Cache 創建的文件從系統臨時文件變成了普通的文件,放在這個目錄裏。

$ls var/mysqld.1/data/#binlog_cache_files                              
ML_140413554102520

頭部保留空間

Binlog cache 的文件裏只包含事務的 Binlog Events,如果要轉成 Binlog 文件,則需要保留一定的空間用來寫 Binlog 文件頭的 Binlog Events,比如 Format_description_event 等。


預留的空間是按 4KB 對齊的,因此至少會預留 4KB。對於大多數情況來說,4KB 的空間已經足夠。但是在一些場景下 Gtid_list_log_event(類似於 MySQL 的 Previous_gtid_event 用來記錄這個 Binlog 之前生成的 Gtid 集合) 可能會非常大。爲了避免在這種情況下這個功能無法使用,在生成新的 Binlog 文件時會根據 Binlog 文件頭部 Events 實際佔用的空間大小來調整保留的空間。當下一個事務開始時,會調整 Binlog Cache 文件的保留空間。

Binlog 頭部的 Binlog Events 通常佔用不到 4KB 的空間,因此在寫完頭部的 Binlog Events 後,可能會剩餘一些空間。如何處理這些剩餘空間呢?得益於 MariaDB Gtid_log_event 可以在末尾填充 0 的機制,這些剩餘空間會被填充到對應的 Gtid_log_event 中。在將 Binlog Cache 文件轉成 Binlog 文件後,其結構如下所示:

Rename 過程


Rename 的主要過程如下:

優化效果

我們仍然用 sysbench 模擬業務執行,然後在後臺每 5 秒執行一個大的 UPDATE,這個 UPDATE 會產生 512MB 的 Binlog Events。測試結果如下:

在有大事務提交優化的情況下, sysbench 的 TPS 已經比較平穩,不會出現劇烈的抖動。看起來每 5 秒仍然會有一個小幅的抖動,這個抖動是因爲執行大的 UPDATE 本身要佔用一定的 CPU,而不是事務提交導致的。

此外我們也模擬了不同大小的事務,對業務 SQL 造成的延遲情況。結果如下圖所示:

總結

在 MySQL Binlog 複製架構中,大事務是一個比較典型的問題導火索,會導致穩定性、複製延遲等問題。通過將 Binlog Cache 的臨時文件直接轉成 Binlog 文件的方法,可以避免對於 Binlog Events 的拷貝,消除額外的 IO,讓大事務的提交始終保持高效和穩定。因此徹底解決了大事務提交導致的各種穩定性問題。

引用鏈接

[1] MariaDB-11.7: https://mariadb.com/resources/blog/binlog-commit-optimization-for-large-transaction/

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/ET5IrNoqHoAC-BaHPYoFGw