OBServer啟動恢復解析
作者:令川,一個在OceanBase專注打造穩定可靠好用儲存引擎的研發同學。
OceanBase是一個單程式軟體,程式名叫:observer。
本文簡單介紹程式observer啟動後的邏輯,裡面包含程式恢復的邏輯。本文對排查程式observer啟動失敗原因有一定參考作用。
目錄結構
在標準配置下,observer程式的執行目錄結構如下所示,介紹其中幾個比較關鍵的目錄和其中的檔案內容。
1.bin目錄下存放是observer以及一些其他工具的二進位制檔案
2.etc目錄下最主要的是的配置項檔案,尤其是程式的一些啟動引數
3.log目錄下是程式執行日誌,通常用於排查問題或反映系統執行的記錄。
4.store目錄下存放的是儲存引擎關係最緊密的日誌和資料檔案了。它們的目錄通常會是一個軟連線,用於單獨掛載磁碟。
日誌目錄有3個,分別是clog/ilog/slog。clog是資料的commit log或redo log。ilog是clog的索引,暫時可以不用瞭解。slog是儲存引擎的redo log,是後設資料的日誌。三種日誌的檔案都是一組以單調遞增序號為名字的檔案。
sstable目錄顧名思義,存放的就是我們的資料啦。OceanBase和其他多檔案資料庫不同,使用統一的2M塊來組織和管理資料和後設資料。因此在sstable目錄下,會看到一個名為block_file的大檔案。
$ob_dir
├── bin
│ ├── ob_admin
│ ├── obproxy
│ └── observer
├── etc
│ ├── io_resource.conf
│ └── observer.config.bin
├── lib
│ ├── libmysqlclient.so.18
│ └── libstdc++.so.6
├── log
│ ├── election.log
│ ├── observer.log
│ └── rootservice.log
└── store
├── clog -> /data/1/clog
│ └── 1
├── ilog -> /data/1/clog
│ └── 1
├── slog -> /data/2/clog
│ └── 1
└── sstable -> /data/2/clog
└── block_file
OB的WAL
在介紹啟動恢復流程前,簡單介紹下OceanBase的WAL機制。WAL機制的原理就不重複展開了。在OceanBase裡,後設資料和資料的WAL日誌是分開的,即上一節在目錄結構下看到的slog和clog。
slog是單機引擎日誌,當在節點上建立修改或是銷燬分割槽、生成新sstable、移除舊sstable等後設資料結構修改發生時,都會先寫slog,而後修改記憶體中的後設資料。後臺定期會將分割槽和sstable的後設資料以快照的形式寫在2M塊上,也就是slog的checkpoint機制。
clog是資料的redo log。當有資料修改發生時,請求會到達leader副本所在節點,leader會通過paxos協議先將日誌同步寫到其他follower的副本節點上。當有多數派節點的日誌寫盤成功後,資料修改成功,會再插入到記憶體中的memory table上。LSM Tree架構下,當memory table到達閾值後,會觸發凍結和轉儲,資料會以sstable的形式寫在block_file的巨集塊內。而此時的clog回放位點會推進,類似於做了checkpoint。
因為clog涉及了事務和paxos協議,需要在多個副本間協商和同步。而slog是單機引擎的後設資料日誌,不涉及多節點的同步和一致性問題。因此clog和slog在物理和實現上是分開的兩套日誌。
資料恢復流程解析
用一句話簡單描述OBServer的啟動恢復,就是要將store目錄下的日誌和資料一字不差的還原到記憶體中,將程式的狀態恢復到當機前的狀態。在介紹具體的流程前,我們先了解下後設資料和資料在磁碟上的組織格式。
快照組織格式
在記憶體中,observer程式是以partition-table store-sstable這三層物件來管理資料的。因為一些歷史原因,目前partition物件在程式碼中以
ObPartitonGroup
來實現;table store是分割槽內的memory table和sstable集合,程式碼實現在
ObTableStore
。SSTable則對應一組資料巨集塊(
ObSSTable
類)。
前面我們提到OceanBase在磁碟上使用2M大小的巨集塊來存放後設資料和資料。當觸發後設資料快照時,每個分割槽都會呼叫各自的
serialize
介面,將序列化資料寫到巨集塊內,這些塊我們稱之為meta block。一個meta block只有2M,不一定能存下所有分割槽的後設資料。因此所有meta block都會以連結串列的形式串聯起來,直到最後一個塊,我們稱之為入口塊
ObSuperBlockMetaEntry
。入口塊最終會持久化在block_file的第1和第2個巨集塊上,這兩個巨集塊我們稱為super block。super block上還會記錄一些其他資訊,例如slog的起始回放位點等等。
struct ObSuperBlockMetaEntry {
blocksstable::MacroBlockId macro_block_id_; // first entry meta macro block id
};
struct ServerSuperBlockContent {int64_t create_timestamp_; // create timestampint64_t modify_timestamp_; // last modified timestampint64_t macro_block_size_;
int64_t total_macro_block_count_;
int64_t total_file_size_;
common::ObLogCursor replay_start_point_;
ObSuperBlockMetaEntry super_block_meta_;
ObSuperBlockMetaEntry tenant_config_meta_;
};
struct ObServerSuperBlock {
ObSuperBlockHeaderV2 header_;
ServerSuperBlockContent content_;
};
因此,當server啟動時,會先從block_file的第1和第2個super block中讀出上一次快照的後設資料入口塊,接著從這些入口塊中,逐個呼叫partition、table store和sstable的
deserialize
介面,將物件恢復到記憶體中去。
啟動流程
observer程式的啟動程式碼從main函式裡一目瞭然,分為三個階段:初始化、啟動、執行。看過或熟悉OB程式碼的同學對於init/start/wait這三個介面不會陌生。最主要的幾大元件都會有這三個介面,分別在上述的三個階段中被呼叫。
ObServer& observer = ObServer::get_instance();
if (OB_FAIL(observer.init(opts, log_cfg))) {
LOG_ERROR("observer init fail", K(ret));
} else if (OB_FAIL(observer.start())) {
LOG_ERROR("observer start fail", K(ret));
} else if (OB_FAIL(observer.wait())) {
LOG_ERROR("observer wait fail", K(ret));
}
每個元件的start流程就不展開講了。資料和日誌恢復的程式碼入口在
ob_partition_service.cpp
檔案的
ObPartitionService::start()
方法內。主要流程參見下圖,1)載入後設資料的快照點,即將分割槽和sstable的資訊還原進記憶體。2)接著,回放slog,將分割槽和sstable的資訊更新到最新狀態。3)然後,從分割槽的元資訊中獲取clog的回放位點,開始回放clog日誌生成memory table。上述三步完成後,單機資料的恢復流程就告一段落了。
因此OceanBase利用WAL和快照機制相結合,保證了節點在當機後,仍然能夠從磁碟的持久化資訊中心恢復出當機前的狀態,保證了資料的完整性。
程式碼參考
後設資料快照和載入程式碼實現,可以參見
ObServerCheckpointWriter
和
ObServerCheckpointLogReader
類。
slog的重啟回放程式碼主要在
ObStorageLogReplayer
類中。
clog的重啟回放程式碼相對會複雜一些,有興趣的同學可以挖一下
ObLogScanRunnable
這個類。
slog的讀寫庫參見
ObStorageLogReader
和
ObStorageLogWriter
。
clog的讀寫庫參見
ObLogDirectReader
和
ObClogWriter
。
今天我們隨著OBServer的啟動流程,探尋了OB的WAL和快照機制,瞭解了儲存引擎內部多個層次物件,以及它們是如何協同工作保證資料的完整性。過程中,還有許多點並沒有展開去講,其中有不少有趣之處可再細細介紹。歡迎你也加入OceanBase,探索資料庫的樂趣,一起做最先進的分散式資料庫!
最後的最後:如果您有任何疑問,可以通過以下方式與我們進行交流:
微信群:掃碼新增小助手,將拉你進群喲~
釘釘群:33254054
今日之星,明日之星都不如你留下的星星(⭐️️)
我們想讓 Github 上優質的開源專案被更多人看到。
文件都是我們精心整理。如果有幫助的話 求個star(◕ᴗ◕✿),鼓勵鼓勵我們喲!
也歡迎大家給我們 提 issue,請點選 這裡。運營小姐姐在此跪謝️️ ❥(^_-)
歡迎大家一起參與 社群貢獻,指南請參考看 這裡
社群答疑:請點選 這裡
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70005215/viewspace-2795140/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Android Service重啟恢復(Service程式重啟)原理解析Android
- Observer原始碼解析Server原始碼
- 非易失性WAL BUFFER實現機制解析:啟動恢復流程改造
- PostgreSQL啟動恢復期間,恢復到的時間線的確定SQL
- 蘋果電腦進入 Macos 恢復啟動蘋果Mac
- 【資料庫資料恢復】無法啟動MongoDB服務的資料恢復案例資料庫資料恢復MongoDB
- win10快速啟動欄找不到怎麼恢復 win10快速啟動欄不見了的恢復步驟Win10
- PostgreSQL啟動恢復透過checkpoint open wal檔案SQL
- MySQL備份與恢復操作解析MySql
- PostgreSQL 恢復大法 - 恢復部分資料庫、跳過壞塊、修復無法啟動的資料庫SQL資料庫
- 資料庫資料恢復——Windows無法啟動MongoDB服務的資料恢復案例資料庫資料恢復WindowsMongoDB
- 【伺服器資料恢復】同友儲存無法啟動的資料恢復案例伺服器資料恢復
- win10啟用快速啟動不見了 win10快速啟動欄如何恢復Win10
- PostgreSQL啟動恢復過程中日誌源的切換SQL
- 3.1.5.7 啟動例項、掛載資料庫並啟動完整的媒體恢復資料庫
- 域名暫停解析是怎麼回事?如何恢復解析?
- 怎樣用恢復驅動器來恢復win10 使用恢復驅動器恢復win10系統的步驟Win10
- 解析ESX SERVER故障資料恢復方法Server資料恢復
- 【資料庫資料恢復】MongoDB資料庫服務啟動失敗的資料恢復案例資料庫資料恢復MongoDB
- 【儲存資料恢復案例】儲存斷電後無法成功重啟,虛擬機器無法啟動-資料恢復資料恢復虛擬機
- 資料庫資料恢復—MongoDB資料庫檔案丟失,啟動報錯的資料恢復案例資料庫資料恢復MongoDB
- 【資料庫資料恢復】突然斷電造成Syabse資料庫無法啟動的資料恢復案例資料庫資料恢復
- 行動硬碟資料恢復硬碟資料恢復
- 快速啟動:基於CRaC實現Spring Boot 3恢復預熱Spring Boot
- PostgreSQL啟動恢復讀取checkpoint記錄失敗的條件SQL
- docker mysql8.0 啟動,掛資料卷,定時備份,恢復~DockerMySql
- Ubuntu boot分割槽檔案誤刪,系統無法啟動_恢復Ubuntuboot
- win10開啟方式被修改怎麼恢復_win10恢復開啟方式的設定方法Win10
- word自動儲存的檔案怎麼恢復,word檔案恢復
- 伺服器資料恢復-伺服器重啟藍色畫面的資料恢復案例伺服器資料恢復
- 【虛擬機器資料恢復】異常斷電導致虛擬機器無法啟動的資料恢復案例虛擬機資料恢復
- 深入解析:段頭塊損壞bbed異常恢復
- RMAN深入解析之--Incarnation應用(不完全恢復)
- 伺服器重啟後掉線資料恢復伺服器資料恢復
- 固態行動硬碟資料恢復硬碟資料恢復
- 【北亞資料恢復】行動硬碟不認盤怎麼恢復硬碟資料?資料恢復硬碟
- VSAN儲存結構解析+儲存資料恢復案例資料恢復
- 【伺服器資料恢復】異常斷電導致虛擬機器檔案丟失不能啟動的資料恢復案例伺服器資料恢復虛擬機