mysql多執行緒slave的演化
sql_thread:
exec_relay_log_event
apply_event_and_update_pos
apply_event
rows_log_event::apply_event
storage_engine operation
update_pos
由於其是單執行緒, 經常會造成備庫延遲;
mysql-transfer
其中只有preparer/applier程式可以有多個
- reader:讀取redo記錄傳遞給preparer程式
- preparer: 根據redo記錄和資料字典資訊生成LCR
- builder: 將同一個事務的LCR打包。對於大事務(eager transaction),可能被打成多個事務包(transaction chunk),那麼可能有些包裡是不包含commit的,每一個事務包都可能交給不同的applier程式。
- analyzer:分析事務包之間的依賴關係
- coordinator:將分析好的事務包交給applier程式
- applier:將事務包應用,如果事務包依賴其他事務包,則需要等待相應的事務包完成。事務能否commit,可能還需要根據不同的情況從coordinator獲得相應的資訊。
5.6並行複製
5.6 中,引入了多執行緒模式,在保留io_thread的前提下,將sql_thread改造為coordinator,並新增多個worker_thread即MTS:
Relay Log File ------- | W01 | ---> Worker 01 (W01) ------- | W01 | ---> SQL THREAD ---> Worker 02 (W02) ------- | W02 | ---> Worker 03 (W03) ------- | ... |
coordinator_thread: 負責讀取 relay log,將讀取的binlog event以事務為單位分發到各個 worker thread 進行執行,並在必要時以序列方式執行binlog event(Description_format_log_event, Rotate_log_event )。
worker_thread: 執行分配到的binlog event,各個執行緒之間互不影響;
引數slave_parallel_workers用於設定MTS數量;
實現原理
在記憶體中構造一個hash表,維護資料庫和worker_thread的對映關係;
多個資料庫可並行執行,同一個資料庫則只能序列執行;如果事務是跨資料庫行為的,則需要等待已分配的該資料庫的事務全部執行完畢,才會繼續分發,其分配行為的偽碼可以簡單的描述如下:
get_slave_worker
if (contains_partition_info(log_event))
db_name= get_db_name(log_event);
entry {db_name, worker_thread, usage} = map_db_to_worker(db_name);
while (entry->usage > 0)
wait();
return worker;
else if (last_assigned_worker)
return last_assigned_worker;
else
push into buffer_array and deliver them until come across a event that have partition info
需要注意的細節
記憶體的分配與釋放,relay thread 每讀取一個log_event, 則需要 malloc 一定的記憶體,在work執行緒執行完後,則需要free掉;
臨時表的處理,臨時表是和entry繫結在一起的,在執行的時候將entry的臨時表掛在執行執行緒thd下面,但沒有固化,如果在臨時表操作期間,備庫crash,則重啟後備庫會有錯誤;
維護一個繫結資訊的array , 在分發事務的時候,更新繫結資訊,增加相應 entry->usage, 在執行完一個事務的時候,則需要減少相應的entry->usage;
slave worker 資訊的維護,即每個 worker thread執行了哪些事務,執行到的位點是在哪,延遲是如何計算的,如果執行出錯,mts_recovery_group 又是如何恢復的;
總體上說,5.6 的並行複製打破了5.5 單執行緒的複製的行為,只是在單庫下用處不大,並且5.6的並行複製的改動引入了一些重量級的bug
5.7
並行複製的實現新增了另外一種並行的方式,即主庫在 ordered_commit中的第二階段的時候,將同一批commit的 binlog 打上一個相同的seqno標籤,同一時間戳的事務在備庫是可以同時執行的(因為這些事務相互不干涉,所以才能在primary併發commit,因此在備庫同樣也能併發執行),因此大大簡化了並行複製的邏輯,並打破了相同 DB 不能並行執行的限制。備庫在執行時,具有同一seqno的事務在備庫可以並行的執行,互不干擾,也不需要繫結資訊,後一批seqno的事務需要等待前一批相同seqno的事務執行完後才可以執行。
5.7實現了MTS下的SLAVE_TRANSACTION_RETRIES
1 當某個worker thread執行事務遭遇錯誤,則根據引數定義再次執行;
2 單個worker thread重試期間不影響其他wokrer thread;
3 若嘗試SLAVE_TRANSACTION_RETRIES仍然失敗,則worker stop,進而通知其他worker和coordinator stop,slave停止更新;
coordinator照舊將event包裝成Slave_job_item形式轉發,但是多加入event的起始位置資訊(binlog name + offset);
worker執行事務組時記錄第一個event的起始位置,當執行出錯時,事務組的event可分為3類:
1 已經執行成功的
2 引發錯誤的
3 尚未執行的(仍在job queue中)
worker無需從relay log讀取整個事務組,只需part 1和part 2部分;
注: relay thread 每讀取一個log_event, 則需要 malloc 一定的記憶體,在work執行緒執行完後,則需要free掉;因此需要重新讀取;
typedef struct slave_job_item
{
void *data;
+ uint relay_number;
+ my_off_t relay_pos;
} Slave_job_item;
http://dev.mysql.com/worklog/task/?id=6964
1 當某個worker thread執行事務遭遇錯誤,則根據引數定義再次執行;
2 單個worker thread重試期間不影響其他wokrer thread;
3 若嘗試SLAVE_TRANSACTION_RETRIES仍然失敗,則worker stop,進而通知其他worker和coordinator stop,slave停止更新;
coordinator照舊將event包裝成Slave_job_item形式轉發,但是多加入event的起始位置資訊(binlog name + offset);
worker執行事務組時記錄第一個event的起始位置,當執行出錯時,事務組的event可分為3類:
1 已經執行成功的
2 引發錯誤的
3 尚未執行的(仍在job queue中)
worker無需從relay log讀取整個事務組,只需part 1和part 2部分;
注: relay thread 每讀取一個log_event, 則需要 malloc 一定的記憶體,在work執行緒執行完後,則需要free掉;因此需要重新讀取;
typedef struct slave_job_item
{
void *data;
+ uint relay_number;
+ my_off_t relay_pos;
} Slave_job_item;
http://dev.mysql.com/worklog/task/?id=6964
mysql-transfer
這是淘寶自主開發的一個基於MySQL+patch後得到的主從同步工具。
其主要目的是為了解決原生版本的主從同步裡,從庫是單執行緒apply主庫的binlog,導致的延遲。
說明:左上角是Master, 右上角是Transfer,下面是Slave。
1、 由於Transfer是在MySQL基礎上打的patch,因此支援幾乎所有MySQL的監控命令,你原來加在Slave上的監控,可以直接改到Transfer上。
2、 一般我們將Transfer和Slave放在同一個機器上(等於是裝兩個MySQL,一個是Transfer,一個是真正的slave)
3、 Transfer按照表名hash將不同表的更新分配到不同的執行緒,因此在多表環境下才能看得到效能提升
4、 Master的binlog格式必須設定成row
5、 若需要用到多個Master,給每個Master命令一個channel,命令 序列為 change master channel1 to master_log_file=xxx…… ; start slave channel1; 可以單獨對一個chanel執行start\stop等命令
6、 若只需要一個master,則語法格式不變
transfer 2.0
Transfer第一版本存在兩個可改進的點:單表併發和事務支援。
a) Transfer2.0支援單表併發,基本原理就是按照更新行的主鍵id (因此有一個限制是同步的表必須要有主鍵)。
b) Transfer2.0支援slave回放主庫事務時以事務為單位執行。
Transfer的推薦配置結構是
Master ==> Transfer ==> Slave
也可以將transfer直接patch到slave上,這樣就不必為tranfer單獨建立一個例項;
patch地址
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15480802/viewspace-1430099/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 多執行緒C++更新MYSQL執行緒C++MySql
- 多執行緒和多執行緒同步執行緒
- 執行緒以及多執行緒,多程式的選擇執行緒
- 多執行緒-多執行緒常見的面試題執行緒面試題
- 多執行緒【執行緒池】執行緒
- 多執行緒--執行緒管理執行緒
- Java多執行緒——執行緒Java執行緒
- 執行緒與多執行緒執行緒
- VC多執行緒 C++ 多執行緒執行緒C++
- 多執行緒-執行緒控制之休眠執行緒執行緒
- 多執行緒-執行緒控制之加入執行緒執行緒
- 多執行緒-執行緒控制之禮讓執行緒執行緒
- 多執行緒-執行緒控制之中斷執行緒執行緒
- Java多執行緒-執行緒池的使用Java執行緒
- 多執行緒(五)---執行緒的Yield方法執行緒
- 【Java多執行緒】執行緒安全的集合Java執行緒
- 多執行緒-程式和執行緒的概述執行緒
- MySQL多執行緒併發調優MySql執行緒
- mysql多執行緒匯出匯入MySql執行緒
- 多執行緒之初識執行緒執行緒
- Java多執行緒-執行緒中止Java執行緒
- Java多執行緒——執行緒池Java執行緒
- 多執行緒-執行緒概述等執行緒
- 多執行緒系列(1),多執行緒基礎執行緒
- 多執行緒系列(二):多執行緒基礎執行緒
- 多執行緒------執行緒與程式/執行緒排程/建立執行緒執行緒
- 多執行緒-執行緒控制之守護執行緒執行緒
- C#多執行緒學習(四) 多執行緒的自動管理(執行緒池)C#執行緒
- C# 多執行緒學習(4) :多執行緒的自動管理(執行緒池)C#執行緒
- a、多執行緒執行緒
- java多執行緒之執行緒的基本使用Java執行緒
- 【Java】【多執行緒】執行緒的生命週期Java執行緒
- 多執行緒-執行緒組的概述和使用執行緒
- 多執行緒-執行緒池的概述和使用執行緒
- C#中的執行緒(三)多執行緒C#執行緒
- 多執行緒的概述執行緒
- 多執行緒的概念執行緒
- java 多執行緒守護執行緒Java執行緒