MySQL核心月報2015.01-MySQL·優化改進·複製效能改進過程
前言
與oracle 不同,mysql 的主庫與備庫的同步是通過 binlog 實現的,而redo日誌只做為mysql 例項的crash recovery使用。mysql在4.x 的時候放棄redo 的同步策略而引入 binlog的同步,一個重要原因是為了相容其它非事務儲存引擎,否則主備同步是沒有辦法進行的。
redo 日誌同步屬於物理同步方法,簡單直接,將修改的物理部分傳送到備庫執行,主備共用一致的 LSN,只要保證 LSN 相同即可,同一時刻,只能主庫或備庫一方接受寫請求; binlog的同步方法屬於邏輯複製,分為statement 或 row 模式,其中statement記錄的是SQL語句,Row 模式記錄的是修改之前的記錄與修改之後的記錄,即前映象與後映象;備庫通過binlog dump 協議拉取binlog,然後在備庫執行。如果拉取的binlog是SQL語句,備庫會走和主庫相同的邏輯,如果是row 格式,則會呼叫儲存引擎來執行相應的修改。
本文簡單說明5.5到5.7的主備複製效能改進過程。
replication improvement (from 5.5 to 5.7)
(1) 5.5 中,binlog的同步是由兩個執行緒執行的
io_thread: 根據binlog dump協議從主庫拉取binlog, 並將binlog轉存到本地的relaylog;
sql_thread: 讀取relaylog,根據位點的先後順序執行binlog event,進而將主庫的修改同步到備庫,達到主備一致的效果; 由於在主庫的更新是由多個客戶端執行的,所以當壓力達到一定的程度時,備庫單執行緒執行主庫的binlog跟不上主庫執行的速度,進而會產生延遲造成備庫不可用,這也是分庫的原因之一,其SQL執行緒的執行堆疊如下:
(2) 5.6 中,引入了多執行緒模式,在多執行緒模式下,其執行緒結構如下
io_thread: 同5.5
Coordinator_thread: 負責讀取 relay log,將讀取的binlog event以事務為單位分發到各個 worker thread 進行執行,並在必要時執行binlog event(Description_format_log_event, Rotate_log_event 等)。
worker_thread: 執行分配到的binlog event,各個執行緒之間互不影響;
多執行緒原理
sql_thread 的分發原理是依據當前事務所操作的資料庫名稱來進行分發,如果事務是跨資料庫行為的,則需要等待已分配的該資料庫的事務全部執行完畢,才會繼續分發,其分配行為的偽碼可以簡單的描述如下:
需要注意的細節
-
- 記憶體的分配與釋放。relay thread 每讀取一個log_event, 則需要 malloc 一定的記憶體,在work執行緒執行完後,則需要free掉;
- 資料庫名 與 worker 執行緒的繫結資訊在一個hash表中進行維護,hash表以entry為單位,entry中記錄當前entry所代表的資料庫名,有多少個事務相關的已被分發,執行這些事務的worker thread等資訊;
- 維護一個繫結資訊的array , 在分發事務的時候,更新繫結資訊,增加相應 entry->usage, 在執行完一個事務的時候,則需要減少相應的entry->usage;
- slave worker 資訊的維護,即每個 worker thread執行了哪些事務,執行到的位點是在哪,延遲是如何計算的,如果執行出錯,mts_recovery_group 又是如何恢復的;
- 分配執行緒是以資料庫名進行分發的,當一個例項中只有一個資料庫的時候,不會對效能有提高,相反,由於增加額外的操作,效能還會有一點回退;
- 臨時表的處理,臨時表是和entry繫結在一起的,在執行的時候將entry的臨時表掛在執行執行緒thd下面,但沒有固化,如果在臨時表操作期間,備庫crash,則重啟後備庫會有錯誤;
總體上說,5.6 的並行複製打破了5.5 單執行緒的複製的行為,只是在單庫下用處不大,並且5.6的並行複製的改動引入了一些重量級的bug
-
- mysql slave sql thread memory leak (http://bugs.mysql.com/bug.php?id=71197)
- Relay log without xid_log_event may case parallel replication hang (http://bugs.mysql.com/bug.php?id=72794)
- Transaction lost when relay_log_info_repository=FILE and crashed (http://bugs.mysql.com/bug.php?id=73482)
(3) 5.7中,並行複製的實現新增了另外一種並行的方式,即主庫在 ordered_commit中的第二階段的時候,將同一批commit的 binlog 打上一個相同的seqno標籤,同一時間戳的事務在備庫是可以同時執行的,因此大大簡化了並行複製的邏輯,並打破了相同 DB 不能並行執行的限制。備庫在執行時,具有同一seqno的事務在備庫可以並行的執行,互不干擾,也不需要繫結資訊,後一批seqno的事務需要等待前一批相同seqno的事務執行完後才可以執行。
詳細實現可參考:http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/6256 。
reference:http://geek.rohitkalhans.com/2013/09/enhancedMTS-deepdive.html
相關文章
- MySQL核心月報2014.11-MySQL· 5.7改進·Recovery改進MySql
- 改進資料庫效能-SQL查詢優化資料庫SQL優化
- MySQL5.6.12的Innodb效能改進MySql
- [個體軟體過程]之過程改進 (轉)
- 使用 ProxySQL 改進 MySQL SSL 的連線效能MySql
- 軟體過程改進中的無奈
- [譯] 使用 Kotlin 協程改進應用效能Kotlin
- MySQL效能優化之簡單sql改寫MySql優化
- Alpha階段複審改進
- 按照oracle效能改進方法論的步驟來優化系統!Oracle優化
- in_list 11g優化器改進優化
- 軟體測試過程的持續改進
- 談軟體開發過程的改進 (轉)
- Chrome渲染管道的效能改進Chrome
- 主題閱讀-IT專案管理-CMMI過程改進專案管理
- 軟體專案管理過程改進與認知過程-轉載專案管理
- [轉貼]:軟體過程改進:經驗和教訓
- Vue 前端許可權控制的優化改進版Vue前端優化
- 【翻譯】.NET 5中的效能改進
- ASP.NET Core 6 的效能改進ASP.NET
- 【譯】.NET 7 中的效能改進(五)
- 【譯】.NET 7 中的效能改進(六)
- 【譯】.NET 7 中的效能改進(一)
- 【譯】.NET 7 中的效能改進(二)
- 【譯】.NET 7 中的效能改進(七)
- 【譯】.NET 7 中的效能改進(八)
- 【譯】.NET 7 中的效能改進(九)
- 【譯】.NET 7 中的效能改進(十)
- 【譯】.NET 7 中的效能改進(三)
- 【譯】.NET 7 中的效能改進(四)
- 【譯】.NET 7 中的效能改進(十一)
- 【譯】.NET 7 中的效能改進(十二)
- 【譯】.NET 7 中的效能改進(十三)
- 在製作遊戲的過程中,我都解決和改進了哪些問題遊戲
- 軟體專案過程診斷與改進建議案例
- GNOME 3.36 釋出,對視覺和效能進行了改進視覺
- MySQL複製效能優化和常見問題分析MySql優化
- MySQL核心月報2014.12-MySQL· 效能優化·threadpool原理分析MySql優化thread