MySQL高可用資料庫核心深度優化的四重定製
作者介紹
王鬆磊,現任職於UCloud,從事MySQL資料庫核心研發工作。主要負責UCloud雲資料庫UDB的核心故障排查工作以及資料庫新特性的研發工作。
近期我們的資料庫團隊對原生複製的多個方面進行了深度優化,提升了UDB高可用資料庫的功能和效能。今天借社群這個平臺,跟大家分享一二。
一、UDB高可用資料庫架構
UDB以虛擬IP、HAProxy、單節點UDB資料庫搭建雙節點高可用架構:
- 雙節點的UDB資料庫保證資料庫資料的全量冗餘,同時保證資料庫的可用性;
- HAProxy在同一時間只連線一個UDB節點,避免多點寫入帶來的資料衝突問題;
- 雙節點HAProxy保證Proxy的可用性;
- 虛擬IP在HAProxy發生宕機時通過IP漂移的方式對HAProxy進行切換,使用者不需要再次修改IP。
在上述架構中,從節點UDB的資料是否完整、是否與主庫保證資料一致性是整個高可用架構的關鍵,所以用於資料傳輸的半同步複製起著至關重要的作用。針對原生的半同步複製,我們作了核心層面的深度優化。
二、UDB資料庫深度優化
UDB是以開源資料庫MySQL Community Server 5.7.16為基線版本,圍繞高可用架構做核心深度優化。
複製流程,如上圖所示,主要經過如下幾個步驟:
- MySQL Server執行SQL成功後,記錄binlog;
- Dump執行緒讀取binlog後,傳送到從機IO執行緒;
- IO執行緒將接收到的binlog記錄到relay log中,同時記錄接收進度到master.info中;
- SQL讀取relay log中的日誌內容進行復現,同時記錄複製日誌的進度到relay-log.info中。
我們在原生複製的基礎上做了核心的深度優化,針對上述流程中的部分步驟,在功能和效能上做了改進,使得 UDB更加穩定。
1、Binlog日誌複製優化
存在的問題
原生半同步複製存在退化問題,在網路抖動導致超時或者從庫追趕主庫日誌進度時,複製會由半同步複製退化為非同步複製。
相比於可靠的半同步複製,非同步複製過程中,從庫是沒有辦法感知接收到relay log與主庫的binlog是否一致。如果發生宕機,也就沒有辦法確認從庫資料是否與主庫一致,是否可以發生資料庫切換,這種不確定的情況是我們不希望看到的。
優化方案
建立雙通道複製,在原有半同步複製的基礎上增加一條UDB複製通道:
- 建立一條新的複製通道與原有的複製並行,兩條通道互相獨立;
- 新的複製通道不傳輸資料,只傳輸主庫的SQL執行進度 (binlog的檔名和位置);
- 新的複製通道使用半同步複製協議,但是不退化,超時後重連,只接收最新的SQL執行進度 ;
- 新的複製通道不存在追補資料的問題,只要網路正常的情況下,從庫永遠可以感知SQL的執行進度。
如上圖所示,當從庫發生宕機或者網路發生故障後,主從複製停止。當從庫複製恢復正常後,原生複製通道通過非同步複製的方式進行資料追補,UDB複製通道只接收最新的binlog記錄位置,這樣可以最大限度地減少主從之間非同步複製的時間。即在網路可連通的情況下,無論何時發生宕機,從庫均知道與主庫是否處於資料一致的狀態(或者落後了多少)。
2、Relay log檔案記錄的優化
存在的問題
在MySQL中,binlog是以event為基本單位進行記錄,以MySQL 5.7 ROW格式(開啟GTID)的binlog為例,一個DML(insert)會以5個event的格式記錄到binlog中(其他操作均以一個或者多個event組成,不再一一羅列),分別為:
- GTID_EVENT:記錄當前事務的GTID
- QUERY_EVENT:事務開始
- TABLE_MAP_EVENT:操作對應的表
- WRITE_ROW_EVENT:插入記錄
- XID_EVENT:提交事務
全部event組成一個完整的事務,完整的事務才會被SQL執行緒正確復現到從庫上。當前IO執行緒接收binlog時,是以event為單位進行接收,即接收到一個event,記錄到relay log中後再繼續接收下一個。這種做法是低效的,也沒有充分利用到MySQL本身的檔案快取。
優化方案
優化IO執行緒記錄relay log的方式,將以event為單位記錄,修改為以事務為單位進行記錄。合併IO執行緒小的IO操作,提高IO效能。
將單個的event寫操作合併為多個event統一寫操作,將小的IO操作合併成較大的IO操作,提高IO效能。
3、Master.info檔案記錄的優化
存在的問題
Master.info檔案在搭建複製時,記錄主庫IP、PORT等連線主庫的相關資訊,在複製過程中,記錄IO執行緒從主庫接收到的binlog的檔名和位置,檔案和位置會在每次記錄relay log成功後更新。
在基於GTID搭建複製後,master.info中記錄的binlog檔案和位置不再作為複製的依據,所以master.info中記錄的binlog的檔案和位置不再是有效的資料,也就沒有必要每次進行更新。
優化方案
在IO執行緒記錄relay log成功後,更新master.info檔案之前,新增判斷。如果開啟了GTID並且使用GTID作為複製的依據(auto_position=1),那麼不再更新master.info中binlog的檔案和位置。
其它的master.info操作仍然保留,如change master、shutdown等操作。
4、Relay log鎖的優化
存在的問題
在IO執行緒和SQL執行緒複製進度相似的情況下,在操作relay log時,會使用同一塊檔案快取,在讀寫檔案快取時,需要加鎖來保證操作的正確性。而IO執行緒和SQL執行緒需要頻繁地讀寫這塊公共記憶體,就需要對同一把鎖頻繁的競爭,從而導致效能下降。
優化方案
將IO執行緒和SQL執行緒對relay log的操作拆分開來,不再使用同一塊檔案快取。雖然這樣做會導致SQL執行緒增加一次讀IO操作。但是消除了對鎖的競爭,大大地提高了IO執行緒和SQL執行緒整體的效能。
三、總結
優化後的複製流程圖如下:
資料庫原生複製流程中包括記錄binlog、記錄relay log、記錄master.info、relay-log.info等,針對上述流程中的部分步驟以及其它未列出的優化,在功能和效能上進行改進,UDB高可用資料庫在功能和效能上均得到了明顯的提升。
文章來自微信公眾號:DBAplus社群