合肥seo優(yōu)化安徽網(wǎng)站關(guān)鍵詞優(yōu)化
本章介紹ceph中比較復(fù)雜的模塊:
Peering機(jī)制。該過(guò)程保障PG內(nèi)各個(gè)副本之間數(shù)據(jù)的一致性,并實(shí)現(xiàn)PG的各種狀態(tài)的維護(hù)和轉(zhuǎn)換。本章首先介紹boost庫(kù)的statechart狀態(tài)機(jī)基本知識(shí),Ceph使用它來(lái)管理PG的狀態(tài)轉(zhuǎn)換。其次介紹PG的創(chuàng)建過(guò)程以及相應(yīng)的狀態(tài)機(jī)創(chuàng)建和初始化。然后詳細(xì)介紹peering機(jī)制三個(gè)具體的實(shí)現(xiàn)階段:GetInfo、GetLog、GetMissing。
statechart狀態(tài)機(jī)
1.1 狀態(tài)
1.2 事件
1.3 狀態(tài)機(jī)的響應(yīng)
1.4 狀態(tài)機(jī)的定義
1.5 context函數(shù)
1.6 事件的特殊處理
1.7 PG狀態(tài)機(jī)
1.8 PG狀態(tài)機(jī)的總體狀態(tài)轉(zhuǎn)換圖
1.9 OSD啟動(dòng)加載PG狀態(tài)機(jī)轉(zhuǎn)換
1.10 PG創(chuàng)建后狀態(tài)機(jī)的狀態(tài)轉(zhuǎn)換
1.11 PG在觸發(fā)Peering過(guò)程時(shí)機(jī)
1. statechart狀態(tài)機(jī)
Ceph在處理PG的狀態(tài)轉(zhuǎn)換時(shí),使用了boost庫(kù)提供的statechart狀態(tài)機(jī)。因此先簡(jiǎn)單介紹一下statechart狀態(tài)機(jī)的基本概念和涉及的相關(guān)知識(shí),以便更好地理解Peering過(guò)程PG的狀態(tài)機(jī)轉(zhuǎn)換流程。下面例舉時(shí)截取了PG狀態(tài)機(jī)的部分代碼。
1.1 狀態(tài)
沒(méi)有子狀態(tài)情況下的狀態(tài)定義
在statechart里,一個(gè)狀態(tài)的定義方式有兩種:
-
struct Reset : boost::statechart::state< Reset, RecoveryMachine >, NamedState {
-
...
-
};
這里定義了狀態(tài)Reset,它需要繼承boost::statechart::state類。該類的模板參數(shù)中,第一個(gè)參數(shù)為狀態(tài)自己的名字Reset,第二個(gè)參數(shù)為該狀態(tài)所屬狀態(tài)機(jī)的名字,表明Reset是狀態(tài)機(jī)RecoveryMachine的一個(gè)狀態(tài)。
有子狀態(tài)情況下的狀態(tài)定義
-
struct Start;
-
struct Started : boost::statechart::state< Started, RecoveryMachine, Start >, NamedState {
-
...
-
}
-
struct Start : boost::statechart::state< Start, Started >, NamedState {
-
};
狀態(tài)Started也是狀態(tài)機(jī)RecoveryMachine的一個(gè)狀態(tài),模板參數(shù)中多了一個(gè)參數(shù)Start,它是狀態(tài)Started的默認(rèn)初始子狀態(tài)。
這里定義的Start是狀態(tài)Started的子狀態(tài)。第一個(gè)模板參數(shù)是自己的名字,第二個(gè)模板參數(shù)是該子狀態(tài)所屬父狀態(tài)的名字。
綜上所述,一個(gè)狀態(tài),要么屬于一個(gè)狀態(tài)機(jī),要么屬于一個(gè)狀態(tài),成為該狀態(tài)的子狀態(tài)。其定義的模板參數(shù)是自己,第二個(gè)參數(shù)是擁有者,第三個(gè)參數(shù)是它的起始子狀態(tài)。
?1.2 事件
狀態(tài)能夠接收并處理事件。事件可以改變狀態(tài),促使?fàn)顟B(tài)發(fā)生轉(zhuǎn)移。在boost庫(kù)的statechart狀態(tài)機(jī)中定義事件的方式如下所示:
-
struct QueryState : boost::statechart::event< QueryState > {
-
Formatter *f;
-
explicit QueryState(Formatter *f) : f(f) {}
-
void print(std::ostream *out) const {
-
*out << "Query";
-
}
-
};
-
};
QueryState為一個(gè)事件,需要繼承boost::statechart::event類,模板參數(shù)為自己的名字。
1.3 狀態(tài)機(jī)的響應(yīng)
在一個(gè)狀態(tài)內(nèi)部,需要定義狀態(tài)機(jī)處于當(dāng)前狀態(tài)時(shí),可以接受的事件以及如何處理這些事件的方法:
-
#define TrivialEvent(T) struct T : boost::statechart::event< T > { \
-
T() : boost::statechart::event< T >() {} \
-
void print(std::ostream *out) const { \
-
*out << #T; \
-
} \
-
};
-
TrivialEvent(Initialize)
-
TrivialEvent(Load)
-
TrivialEvent(GotInfo)
-
TrivialEvent(NeedUpThru)
-
TrivialEvent(NullEvt)
-
TrivialEvent(FlushedEvt)
-
TrivialEvent(Backfilled)
-
TrivialEvent(LocalBackfillReserved)
-
TrivialEvent(RemoteBackfillReserved)
-
TrivialEvent(RejectRemoteReservation)
-
TrivialEvent(RemoteReservationRejected)
-
TrivialEvent(RemoteReservationCanceled)
-
TrivialEvent(RequestBackfill)
-
TrivialEvent(RequestRecovery)
-
TrivialEvent(RecoveryDone)
-
TrivialEvent(BackfillTooFull)
-
TrivialEvent(RecoveryTooFull)
-
TrivialEvent(MakePrimary)
-
TrivialEvent(MakeStray)
-
TrivialEvent(NeedActingChange)
-
TrivialEvent(IsIncomplete)
-
TrivialEvent(IsDown)
-
TrivialEvent(AllReplicasRecovered)
-
TrivialEvent(DoRecovery)
-
TrivialEvent(LocalRecoveryReserved)
-
TrivialEvent(RemoteRecoveryReserved)
-
TrivialEvent(AllRemotesReserved)
-
TrivialEvent(AllBackfillsReserved)
-
TrivialEvent(GoClean)
-
TrivialEvent(AllReplicasActivated)
-
TrivialEvent(IntervalFlush)
-
struct Initial : boost::statechart::state< Initial, RecoveryMachine >, NamedState {
-
explicit Initial(my_context ctx);
-
void exit();
-
typedef boost::mpl::list <
-
boost::statechart::transition< Initialize, Reset >,
-
boost::statechart::custom_reaction< Load >,
-
boost::statechart::custom_reaction< NullEvt >,
-
boost::statechart::transition< boost::statechart::event_base, Crashed >
-
> reactions;
-
boost::statechart::result react(const Load&);
-
boost::statechart::result react(const MNotifyRec&);
-
boost::statechart::result react(const MInfoRec&);
-
boost::statechart::result react(const MLogRec&);
-
boost::statechart::result react(const boost::statechart::event_base&) {
-
return discard_event();
-
}
-
};
狀態(tài)機(jī)的7種事件處理方法?
上述代碼列出了狀態(tài)RecoveryMachine/Initial可以處理的事件列表和處理對(duì)應(yīng)事件的方法:
1) 通過(guò)boost::mpl::list定義該狀態(tài)可以處理多個(gè)事件類型。本例中可以處理Initialize、Load、NullEvt和event_base事件。
2) 簡(jiǎn)單事件處理
boost::statechart::transition< Initialize, Reset >
定義了狀態(tài)Initial接收到事件Initialize后,無(wú)條件直接跳轉(zhuǎn)到Reset狀態(tài);
3) 用戶自定義事件處理: 當(dāng)接收到事件后,需要根據(jù)一些條件來(lái)決定狀態(tài)如何轉(zhuǎn)移,這個(gè)邏輯需要用戶自己定義實(shí)現(xiàn)
boost::statechart::custom_reaction< Load >
custom_reaction 定義了一個(gè)用戶自定義的事件處理方法,必須有一個(gè)react()的處理函數(shù)處理對(duì)應(yīng)該事件。狀態(tài)轉(zhuǎn)移的邏輯需要用戶自己在react函數(shù)里實(shí)現(xiàn):
boost::statechart::result react(const Load&);
4)NullEvt事件用戶自定義處理,但是沒(méi)有實(shí)現(xiàn)react()函數(shù)來(lái)處理,最終事件匹配了boost::statechart::event_base事件,直接調(diào)用函數(shù)discard_event把事件丟棄掉。
-
boost::statechart::custom_reaction< NullEvt >
-
?? ?
-
boost::statechart::result react(const boost::statechart::event_base&) {
-
?? ?return discard_event();
-
? ? ? }
1.4 狀態(tài)機(jī)的定義
RecoveryMachine為定義的狀態(tài)機(jī),需要繼承boost::statechart::state_machine類:
-
? ? struct Initial;
-
? ? class RecoveryMachine : public boost::statechart::state_machine< RecoveryMachine, Initial > {
-
? ? ? RecoveryState *state;
-
? ? public:
-
? ? ? PG *pg;
-
? ? ? }
模板參數(shù)第一個(gè)參數(shù)為自己的名字,第二個(gè)參數(shù)為狀態(tài)機(jī)默認(rèn)的初始狀態(tài)Initial。
狀態(tài)機(jī)的基本操作有兩個(gè):? ?
-
RecoveryMachine machine;
-
? ? PG *pg;
-
? ? explicit RecoveryState(PG *pg)
-
? ? ? : machine(this, pg), pg(pg), orig_ctx(0) {
-
? ? ? machine.initiate();//a---
-
? ? }
-
? ? void handle_event(const boost::statechart::event_base &evt,
-
?? ??? ? ? ? ?RecoveryCtx *rctx) {
-
? ? ? start_handle(rctx);
-
? ? ? machine.process_event(evt);//b---
-
? ? ? end_handle();
-
? ? }
-
? ? void handle_event(CephPeeringEvtRef evt,
-
?? ??? ? ? ? ?RecoveryCtx *rctx) {
-
? ? ? start_handle(rctx);
-
? ? ? machine.process_event(evt->get_event());/b---
-
? ? ? end_handle();
-
? ? }
a.狀態(tài)機(jī)的初始化
initiate()是繼承自boost::statechart::state_machine的成員函數(shù)。
b.函數(shù)process_event()用來(lái)向狀態(tài)機(jī)投遞事件,從而觸發(fā)狀態(tài)機(jī)接收并處理該事件
process_event()也是繼承自boost::statechart::state_machine的成員函數(shù)。
1.5 context函數(shù)
context是狀態(tài)機(jī)的一個(gè)比較有用的函數(shù),它可以獲取當(dāng)前狀態(tài)的所有祖先狀態(tài)的指針。通過(guò)它可以獲取父狀態(tài)以及祖先狀態(tài)的一些內(nèi)部參數(shù)和狀態(tài)值。context()函數(shù)是實(shí)現(xiàn)在boost::statechart::state_machine中的:
context()函數(shù)在boost::statechart::simple_state中有實(shí)現(xiàn):
-
//boost_1_73_0/boost/statechart/simple_state.hpp
-
234 ? ? template< class OtherContext >
-
235 ? ? OtherContext & context()
-
236 ? ? {
-
237 ? ? ? typedef typename mpl::if_<
-
238 ? ? ? ? is_base_of< OtherContext, MostDerived >,
-
239 ? ? ? ? context_impl_this_context,
-
240 ? ? ? ? context_impl_other_context
-
241 ? ? ? >::type impl;
-
242 ? ? ? return impl::template context_impl< OtherContext >( *this );
-
243 ? ? }
-
244 ? ? ?
-
245 ? ? template< class OtherContext >
-
246 ? ? const OtherContext & context() const
-
247 ? ? {
-
248 ? ? ? typedef typename mpl::if_<
-
249 ? ? ? ? is_base_of< OtherContext, MostDerived >,
-
250 ? ? ? ? context_impl_this_context,
-
251 ? ? ? ? context_impl_other_context
-
252 ? ? ? >::type impl;
-
253 ? ? ? return impl::template context_impl< OtherContext >( *this );
-
254 ? ? }
從simple_state的實(shí)現(xiàn)來(lái)看,context()可以獲取當(dāng)前狀態(tài)的祖先狀態(tài)指針,也可以獲取當(dāng)前狀態(tài)所屬狀態(tài)機(jī)的指針。
例如狀態(tài)Started是RecoveryMachine的一個(gè)狀態(tài),狀態(tài)Start是Started狀態(tài)的一個(gè)子狀態(tài),那么如果當(dāng)前狀態(tài)是Start,就可以通過(guò)該函數(shù)獲取它的父狀態(tài)Started的指針:
Started * parent = context< Started >();
同時(shí)也可以獲取其祖先狀態(tài)RecoveryMachine的指針:
RecoveryMachine *machine = context< RecoveryMachine >();
在狀態(tài)機(jī)實(shí)現(xiàn)中,大量了使用該函數(shù)來(lái)獲取相應(yīng)的指針。Eg:
-
? PG *pg = context< RecoveryMachine >().pg;
-
? context< RecoveryMachine >().get_cur_transaction(),
-
? context< RecoveryMachine >().get_on_applied_context_list(),
-
? context< RecoveryMachine >().get_on_safe_context_list());
綜上所述,context()函數(shù)為獲取當(dāng)前狀態(tài)的祖先狀態(tài)上下文提供了一種方法。
<span id = “1.6事件的特殊處理”></span>
1.6 事件的特殊處理
事件除了在狀態(tài)轉(zhuǎn)移列表中觸發(fā)狀態(tài)轉(zhuǎn)移,或者進(jìn)入用戶自定義的狀態(tài)處理函數(shù),還可以有下列特殊的處理方式:
在用戶自定義的函數(shù)里,可以直接調(diào)用函數(shù)transit來(lái)直接跳轉(zhuǎn)到目標(biāo)狀態(tài)。例如:
-
boost::statechart::result PG::RecoveryState::Initial::react(const MLogRec& i)
-
{
-
? PG *pg = context< RecoveryMachine >().pg;
-
? assert(!pg->is_primary());
-
? post_event(i);
-
? return transit< Stray >();//go---
-
}
可以直接跳轉(zhuǎn)到狀態(tài)Stray。在用戶自定義的函數(shù)里,可以調(diào)用函數(shù)post_event()直接產(chǎn)生相應(yīng)的事件,并投遞給狀態(tài)機(jī)
-
PG::RecoveryState::Start::Start(my_context ctx)
-
? : my_base(ctx),
-
? ? NamedState(context< RecoveryMachine >().pg->cct, "Start")
-
{
-
? context< RecoveryMachine >().log_enter(state_name);
-
? PG *pg = context< RecoveryMachine >().pg;
-
? if (pg->is_primary()) {
-
? ? dout(1) << "transitioning to Primary" << dendl;
-
? ? post_event(MakePrimary());//go---
-
? } else { //is_stray
-
? ? dout(1) << "transitioning to Stray" << dendl;?
-
? ? post_event(MakeStray());//go---
-
? }
-
}
在用戶的自定義函數(shù)里,調(diào)用函數(shù)discard_event()可以直接丟棄事件,不做任何處理
-
boost::statechart::result PG::RecoveryState::Primary::react(const ActMap&)
-
{
-
? dout(7) << "handle ActMap primary" << dendl;
-
? PG *pg = context< RecoveryMachine >().pg;
-
? pg->publish_stats_to_osd();
-
? pg->take_waiters();
-
? return discard_event();//go---
-
}
在用戶的自定義函數(shù)里,調(diào)用函數(shù)forward_event()可以把當(dāng)前事件繼續(xù)投遞給狀態(tài)機(jī)
-
boost::statechart::result PG::RecoveryState::WaitUpThru::react(const ActMap& am)
-
{
-
? PG *pg = context< RecoveryMachine >().pg;
-
? if (!pg->need_up_thru) {
-
? ? post_event(Activate(pg->get_osdmap()->get_epoch()));
-
? }
-
? return forward_event();
-
}
結(jié)合?1.3 狀態(tài)機(jī)的響應(yīng)?的3種事件響應(yīng),大概有7種事件響應(yīng)處理的方法。
1.7 PG狀態(tài)機(jī)
在類PG的內(nèi)部定義了類RecoveryState,該類RecoveryState的內(nèi)部定義了PG的狀態(tài)機(jī)RecoveryMachine和它的各種狀態(tài)。
-
class PG{
-
?? ?class RecoveryState{
-
?? ??? ?class RecoveryMachine{
-
?? ??? ?};
-
?? ?};
-
};
在每個(gè)PG創(chuàng)建時(shí),在構(gòu)造函數(shù)里創(chuàng)建一個(gè)新的RecoveryState類的對(duì)象,并創(chuàng)建相應(yīng)的RecoveryMachine類的對(duì)象,也就是創(chuàng)建了一個(gè)新的狀態(tài)機(jī)。每個(gè)PG類對(duì)應(yīng)一個(gè)獨(dú)立的狀態(tài)機(jī)來(lái)控制該P(yáng)G的狀態(tài)轉(zhuǎn)換。
-
PG::PG(OSDService *o, OSDMapRef curmap,
-
? ? ? ?const PGPool &_pool, spg_t p) :
-
?? ?recovery_state(this){
-
}
-
class RecoveryState{
-
public:
-
?? ?explicit RecoveryState(PG *pg)
-
? ? ? : machine(this, pg), pg(pg), orig_ctx(0) {
-
? ? ? machine.initiate();
-
? ? }
-
};
上面machine.initiate()調(diào)用的是boost::statechart::state_machine中的initiate()方法。
1.8 PG狀態(tài)機(jī)的總體狀態(tài)轉(zhuǎn)換圖
下圖為PG狀態(tài)機(jī)的總體狀態(tài)轉(zhuǎn)換圖簡(jiǎn)化版
1.9 OSD啟動(dòng)加載PG狀態(tài)機(jī)轉(zhuǎn)換
當(dāng)OSD重啟時(shí),調(diào)用函數(shù)OSD::init(),該函數(shù)調(diào)用load_pgs()加載已經(jīng)存在的PG,其處理過(guò)程和以下創(chuàng)建PG的過(guò)程相似。
-
int OSD::init()
-
{
-
? // load up pgs (as they previously existed)
-
? load_pgs();
-
}
-
void OSD::load_pgs()
-
{
-
...
-
? ? PG::RecoveryCtx rctx(0, 0, 0, 0, 0, 0);
-
? ? pg->handle_loaded(&rctx);//go--
-
...
-
}
-
void PG::handle_loaded(RecoveryCtx *rctx)
-
{
-
? dout(10) << "handle_loaded" << dendl;
-
? Load evt;
-
? recovery_state.handle_event(evt, rctx);
-
}
-
struct Initial : boost::statechart::state< Initial, RecoveryMachine >, NamedState {
-
? ? typedef boost::mpl::list <
-
?? ?boost::statechart::transition< Initialize, Reset >,
-
?? ?boost::statechart::custom_reaction< Load >,
-
?? ?boost::statechart::custom_reaction< NullEvt >,
-
?? ?boost::statechart::transition< boost::statechart::event_base, Crashed >
-
?? ?> reactions;
-
?? ?
-
? ? boost::statechart::result react(const Load&);
-
}
-
boost::statechart::result PG::RecoveryState::Initial::react(const Load& l)
-
{
-
? PG *pg = context< RecoveryMachine >().pg;
-
? // do we tell someone we're here?
-
? pg->send_notify = (!pg->is_primary());
-
? pg->update_store_with_options();
-
? pg->update_store_on_load();
-
? return transit< Reset >();//go---
-
}
1.10 PG創(chuàng)建后狀態(tài)機(jī)的狀態(tài)轉(zhuǎn)換
?
-
void PG::handle_create(RecoveryCtx *rctx)
-
{
-
? dout(10) << "handle_create" << dendl;
-
? rctx->created_pgs.insert(this);
-
? Initialize evt;
-
? recovery_state.handle_event(evt, rctx);
-
? ActMap evt2;
-
? recovery_state.handle_event(evt2, rctx);
-
? rctx->on_applied->add(make_lambda_context([this]() {
-
? ? update_store_with_options();
-
? }));
-
}
當(dāng)PG創(chuàng)建后,同時(shí)在該類內(nèi)部創(chuàng)建了一個(gè)屬于該P(yáng)G的RecoveryMachine類型的狀態(tài)機(jī),該狀態(tài)機(jī)的初始化狀態(tài)為默認(rèn)初始化狀態(tài)Initial。
在PG創(chuàng)建后,調(diào)用函數(shù)pg->handle_create(&rctx)來(lái)給狀態(tài)機(jī)投遞事件
該函數(shù)首先向RecoveryMachine投遞了Initialize類型的事件。接收到Initialize類型的事件后直接轉(zhuǎn)移到Reset狀態(tài)。其次,向RecoveryMachine投遞了ActMap事件。
-
boost::statechart::result PG::RecoveryState::Reset::react(const ActMap&)
-
{
-
? PG *pg = context< RecoveryMachine >().pg;
-
? if (pg->should_send_notify() && pg->get_primary().osd >= 0) {
-
? ? context< RecoveryMachine >().send_notify(
-
? ? ? pg->get_primary(),
-
? ? ? pg_notify_t(
-
?? ?pg->get_primary().shard, pg->pg_whoami.shard,
-
?? ?pg->get_osdmap()->get_epoch(),
-
?? ?pg->get_osdmap()->get_epoch(),
-
?? ?pg->info),
-
? ? ? pg->past_intervals);
-
? }
-
? pg->update_heartbeat_peers();
-
? pg->take_waiters();
-
? return transit< Started >();//a---
-
}
a. 在自定義的react函數(shù)里直接調(diào)用了transit函數(shù)跳轉(zhuǎn)到Started狀態(tài)。? ?
-
struct Start;
-
? ? struct Started : boost::statechart::state< Started, RecoveryMachine, Start >, NamedState {//這里直接進(jìn)入默認(rèn)子狀態(tài)Start
-
? ? ...
-
? ? }
-
? ? /*-------Start---------*/
-
? ? PG::RecoveryState::Start::Start(my_context ctx)
-
? ? ? : my_base(ctx),
-
? ? ? ? NamedState(context< RecoveryMachine >().pg, "Start")
-
? ? {
-
? ? ? context< RecoveryMachine >().log_enter(state_name);
-
? ??
-
? ? ? PG *pg = context< RecoveryMachine >().pg;
-
? ? ? if (pg->is_primary()) {
-
? ? ? ? ldout(pg->cct, 1) << "transitioning to Primary" << dendl;
-
? ? ? ? post_event(MakePrimary());//go---
-
? ? ? } else { //is_stray
-
? ? ? ? ldout(pg->cct, 1) << "transitioning to Stray" << dendl;
-
? ? ? ? post_event(MakeStray());//go---
-
? ? ? }
-
? ? }
-
? ??
-
? ? struct Start : boost::statechart::state< Start, Started >, NamedState {
-
? ? ? explicit Start(my_context ctx);
-
? ? ? void exit();
-
? ? typedef boost::mpl::list <
-
?? ?boost::statechart::transition< MakePrimary, Primary >,
-
?? ?boost::statechart::transition< MakeStray, Stray >
-
?? ?> reactions;
-
? ? }; ? ?
-
? ??
-
? ? struct Primary : boost::statechart::state< Primary, Started, Peering >, NamedState {//這里直接進(jìn)入Primary的默認(rèn)子狀態(tài)Peering。
-
? ? ...
-
? ? }
-
? ??
-
? ? struct Stray : boost::statechart::state< Stray, Started >, NamedState {
-
? ? ...
-
? ? } ? ?
1.進(jìn)入狀態(tài)RecoveryMachine/Started后,就進(jìn)入RecoveryMachine/Started的默認(rèn)的子狀態(tài)RecoveryMachine/Started/Start中。
由以上代碼可知,在Start狀態(tài)的構(gòu)造函數(shù)中,根據(jù)本OSD在該P(yáng)G中擔(dān)任的角色不同分別進(jìn)行如下處理:
(1)如果是主OSD,就調(diào)用函數(shù)post_event(),拋出事件MakePrimary,進(jìn)入主OSD的默認(rèn)子狀態(tài)Primary/Peering中;
(2)如果是從OSD,就調(diào)用函數(shù)post_event(),拋出事件MakeStray,進(jìn)入Started/Stray狀態(tài);
對(duì)于一個(gè)OSD的PG處于Stray狀態(tài),是指該OSD上的PG副本目前狀態(tài)不確定,但是可以響應(yīng)主OSD的各種查詢操作。它有兩種可能:一種是最終轉(zhuǎn)移到狀態(tài)ReplicaActive,處于活躍狀態(tài),成為PG的一個(gè)副本;另一種可能的情況是:如果是數(shù)據(jù)遷移的源端,可能一直保持Stray狀態(tài),該OSD上的副本可能在數(shù)據(jù)遷移完成后,PG以及數(shù)據(jù)就都被刪除了。
1.11 PG在觸發(fā)Peering過(guò)程時(shí)機(jī):
1.當(dāng)系統(tǒng)初始化時(shí),OSD重新啟動(dòng)導(dǎo)致PG重新加載。
2.PG新創(chuàng)建時(shí),PG會(huì)發(fā)起一次Peering的過(guò)程
3. 當(dāng)有OSD失效,OSD的增加或者刪除等導(dǎo)致PG的acting set發(fā)生了變化,該P(yáng)G就會(huì)重新發(fā)起一次Peering過(guò)程。
參考link:
?https://ivanzz1001.github.io/records/post/ceph/2019/02/01/ceph-src-code-part10_1