MHA選擇主庫原始碼解析
MHA在選擇新的主庫之前,會先把活著的slave分為幾個陣列,分別為latest(最靠前的slave陣列),pref(優先被選擇為master的陣列),bad(不會被選擇成為master的slave),slaves(所有活著的slave陣列)。然後進行5次選擇,從上面的這些組當中挑選出新的master。
選擇latest陣列
foreach (@slaves) {
my $a = $latest[0]{Master_Log_File};
my $b = $latest[0]{Read_Master_Log_Pos};
if (
!$find_oldest
&& (
( !$a && !defined($b) )
|| ( $_->{Master_Log_File} gt $latest[0]{Master_Log_File} )
|| ( ( $_->{Master_Log_File} ge $latest[0]{Master_Log_File} )
&& $_->{Read_Master_Log_Pos} > $latest[0]{Read_Master_Log_Pos} )
)
)
{
@latest = ();
push( @latest, $_ );
}
elsif (
$find_oldest
&& (
( !$a && !defined($b) )
|| ( $_->{Master_Log_File} lt $latest[0]{Master_Log_File} )
|| ( ( $_->{Master_Log_File} le $latest[0]{Master_Log_File} )
&& $_->{Read_Master_Log_Pos} < $latest[0]{Read_Master_Log_Pos} )
)
)
{
@latest = ();
push( @latest, $_ );
}
elsif ( ( $_->{Master_Log_File} eq $latest[0]{Master_Log_File} )
&& ( $_->{Read_Master_Log_Pos} == $latest[0]{Read_Master_Log_Pos} ) )
{
push( @latest, $_ );
}
}
上面程式碼主要的結構就是一個foreach迴圈,一個if判斷。foreach迴圈處理所有的活著的slave。if判斷這裡有三個判斷條件,主要根據Master_Log_File和Read_Master_Log_Pos的大小來判斷。第一個和第二個分別為了找出最靠前和最靠後的slave的。如果滿足條件,那麼就清空latest陣列,把符合條件的放入latest陣列裡面。第三個條件用於找出和latest陣列裡面Master_Log_File和Read_Master_Log_Pos一樣的slave,並放入latest陣列。這樣所有的 最靠前的就都放入latest陣列裡面了。
選擇pref陣列
foreach (@servers) {
next if ( $_->{dead} eq `1` );
if ( $_->{candidate_master} >= 1 ) {
push( @ret_servers, $_ );
}
}
迴圈處理所有的配置server,已經死了的slave跳過,有引數candidate_master=1的slave放入pref陣列,會被優先推舉為新的master。
選擇bad陣列
foreach (@servers) {
if (
$_->{no_master} >= 1
|| $_->{log_bin} eq `0`
|| $_->{oldest_major_version} eq `0`
|| (
$latest_slave
&& ( $check_replication_delay
&& $self->check_slave_delay( $_, $latest_slave ) >= 1 )
)
)
{
push( @ret_servers, $_ );
}
}
也是迴圈處理所有的配置的server,滿足下面三個條件之一就會被選擇放入bad陣列,也就說這些slave不會被推選為新的master。
新增了引數no_master=1
沒有開啟binlog
如果延遲太大,如何才算是複製延遲太大呢?
( $latest->{Master_Log_File} gt $target->{Relay_Master_Log_File} )
|| ( $latest->{Read_Master_Log_Pos} >
$target->{Exec_Master_Log_Pos} + 100000000 )
這裡的latest就是上面選擇出來最靠前的第一個latest slave,不過所有的latest都是一樣的,所以選擇哪一個用於比較都是沒關係的。要麼latest的master_log_file > 對比者的Relay_Master_Log_File。或者是兩者相同,但是latest的Read_Master_Log_Pos > 對比者的Exec_Master_Log_Pos+1億。如果設定了引數check_repl_delay=0,那就不會會檢查複製延遲。
選擇slaves陣列
只要是活著的slave都會被放進slaves陣列當中。
這裡需要說明的是,一個slave可以放進多個陣列當中。不是一個slave只能存放到一個陣列當中。
第一次選擇:
return $latest[0] if ( $#pref < 0 && $#bad < 0 && $latest[0]->{latest_priority} );
如果pref和bad陣列當中slave的個數為0,則選擇latest陣列當中的第一個slave為master。
第二次選擇:
$log->info(
" Searching from candidate_master slaves which have received the latest relay log events.."
) if ( $#pref >= 0 );
foreach my $h (@latest) {
foreach my $p (@pref) {
if ( $h->{id} eq $p->{id} ) {
return $h
if ( !$self->get\_server\_from\_by\_id( @bad, $p->{id} ) );
}
}
}
$log->info(" Not found.") if ( $#pref >= 0 );
迴圈對比latest陣列和perf陣列的slave,如果存在相同的slave,並且這個slave不在bad陣列當中,該slave會被推選為新的master。
第三次選擇:
foreach my $s (@slaves) {
foreach my $p (@pref) {
if ( $s->{id} eq $p->{id} ) {
my $a = $self->get_server_from_by_id( @bad, $p->{id} );
return $s unless ($a);
}
}
}
迴圈對比slaves陣列pref陣列當中的slave,如果有一個slave相同並且不在bad陣列當中,該就會成為新的master。
第四次選擇:
foreach my $h (@latest) {
my $a = $self->get_server_from_by_id( @bad, $h->{id} );
return $h unless ($a);
}
迴圈latest陣列,如果有迴圈到的slave不在bad陣列當中,這個slave就會成為master。也就是說就算新增了candidate_master=1,該slave也不一定會成為主庫。
第五次選擇:
foreach my $s (@slaves) {
my $a = $self->get_server_from_by_id( @bad, $s->{id} );
return $s unless ($a);
}
從活著的slave當中進行迴圈,如果迴圈到的slave不在bad陣列當中,那麼這個slave就會成為主庫。 如果進行了5次選擇都找不到主庫,那麼主庫選擇失敗,failover失敗。
原文釋出時間為:2018-04-11
本文作者:魏新平
本文來自雲棲社群合作伙伴“老葉茶館”,瞭解相關資訊可以關注“老葉茶館”。
相關文章
- MySQL MHA原始碼解析MySql原始碼
- 【MySQL】MHA原始碼之主庫選取(二)MySql原始碼
- MHA原始碼分析原始碼
- 知乎 Matisse 原始碼解析,帶你探究高效圖片選擇庫的祕密原始碼
- MHA原始碼分析——環境部署原始碼
- 【RocketMQ】DLedger選主原始碼分析MQ原始碼
- jQuery原始碼剖析 (二) - 選擇器jQuery原始碼
- jQuery 原始碼學習 (六) 選擇器jQuery原始碼
- MPTCP 原始碼分析(三) 子路徑選擇TCP原始碼
- 【原始碼】MATLAB特徵選擇函式庫version 6.2.2018.1原始碼Matlab特徵函式
- 直播帶貨原始碼,日期時間選擇器 選擇範圍限制原始碼
- Kudu主鍵選擇策略
- 直播系統原始碼,選擇驗證方式時選擇郵箱驗證原始碼
- 短視訊系統原始碼,點選選擇框,底部彈出可以選擇的選項原始碼
- seo之前網站原始碼或模板選擇網站原始碼
- 直播app原始碼,資料庫多資料來源自動選擇實現APP原始碼資料庫
- OkHttp 原始碼剖析系列(五)——代理路由選擇HTTP原始碼路由
- lodash原始碼分析之快取方式的選擇原始碼快取
- 影片直播原始碼,圖片選擇器ImagePicker原始碼
- 【MySQL】MHA原始碼之監控檢查(一)MySql原始碼
- mysql主從選擇性同步某幾個庫實現方法MySql
- OkHttp 開源庫使用與原始碼解析HTTP原始碼
- 小而美的Promise庫——promiz原始碼解析Promise原始碼
- 一個golang並行庫原始碼解析Golang並行原始碼
- Android開源庫——EventBus原始碼解析Android原始碼
- 直播系統定製開發選擇開原始碼已成折中之選原始碼
- Android 資料庫 ObjectBox 原始碼解析Android資料庫Object原始碼
- 【原始碼解析】- ArrayList原始碼解析,絕對詳細原始碼
- 原始碼解析.Net中Host主機的構建過程原始碼
- 編碼的選擇
- 不懂技術,如何選擇一套原始碼系統?原始碼
- Element原始碼分析系列7-Select(下拉選擇框)原始碼
- 直播app原始碼,map實現購物車選擇功能APP原始碼
- Mysql MHA部署-02主從複製MySql
- MHA高可用架構工作原理?主庫當機處理過程架構
- MHA實現mysql主從資料庫手動切換的方法MySql資料庫
- Spark原始碼-SparkContext原始碼解析Spark原始碼Context
- 一對一聊天原始碼,驗證碼選擇輸入字母驗證原始碼