數(shù)據(jù)庫|TiDB多副本損壞,別著急!有損恢復(fù)幫你化險為夷!
高文鋒?|后端開發(fā)工程師
一、前言
TiDB分布式數(shù)據(jù)庫采用多副本機制,數(shù)據(jù)副本通過 Multi-Raft 協(xié)議同步事務(wù)日志,確保數(shù)據(jù)強一致性且少數(shù)副本發(fā)生故障時不影響數(shù)據(jù)的可用性。在三副本情況下,單副本損壞可以說對集群沒什么影響,但當(dāng)遇到多副本損壞的損壞丟失的時候,如何快速恢復(fù)也是DBA需要面對的問題,本次主要講述對TiDB對多副本損壞丟失的處理方法。
二、TiDB數(shù)據(jù)庫的存儲架構(gòu)

TiDB Server:SQL 層,對外暴露 MySQL 協(xié)議的連接 endpoint,負責(zé)接受客戶端的連接,執(zhí)行 SQL 解析和優(yōu)化,最終生成分布式執(zhí)行計劃。TiDB 層本身是無狀態(tài)的,實踐中可以啟動多個 TiDB 實例,通過負載均衡組件(如 LVS、HAProxy 或 F5)對外提供統(tǒng)一的接入地址,客戶端的連接可以均勻地分攤在多個 TiDB 實例上以達到負載均衡的效果。TiDB Server 本身并不存儲數(shù)據(jù),只是解析 SQL,將實際的數(shù)據(jù)讀取請求轉(zhuǎn)發(fā)給底層的存儲節(jié)點 TiKV(或 TiFlash)。
PD (Placement Driver) Server:整個 TiDB 集群的元信息管理模塊,負責(zé)存儲每個 TiKV 節(jié)點實時的數(shù)據(jù)分布情況和集群的整體拓撲結(jié)構(gòu),提供 TiDB Dashboard 管控界面,并為分布式事務(wù)分配事務(wù) ID。PD 不僅存儲元信息,同時還會根據(jù) TiKV 節(jié)點實時上報的數(shù)據(jù)分布狀態(tài),下發(fā)數(shù)據(jù)調(diào)度命令給具體的 TiKV 節(jié)點,可以說是整個集群的“大腦”。此外,PD 本身也是由至少 3 個節(jié)點構(gòu)成,擁有高可用的能力。建議部署奇數(shù)個 PD 節(jié)點。
存儲節(jié)點TiKV Server:負責(zé)存儲數(shù)據(jù),從外部看 TiKV 是一個分布式的提供事務(wù)的 Key-Value 存儲引擎。存儲數(shù)據(jù)的基本單位是 Region,每個 Region 負責(zé)存儲一個 Key Range(從 StartKey 到 EndKey 的左閉右開區(qū)間)的數(shù)據(jù),每個 TiKV 節(jié)點會負責(zé)多個 Region。TiKV 的 API 在 KV 鍵值對層面提供對分布式事務(wù)的原生支持,默認提供了 SI (Snapshot Isolation) 的隔離級別,這也是 TiDB 在 SQL 層面支持分布式事務(wù)的核心。TiDB 的 SQL 層做完 SQL 解析后,會將 SQL 的執(zhí)行計劃轉(zhuǎn)換為對 TiKV API 的實際調(diào)用。所以,數(shù)據(jù)都存儲在 TiKV 中。另外,TiKV 中的數(shù)據(jù)都會自動維護多副本(默認為三副本),天然支持高可用和自動故障轉(zhuǎn)移。
TiFlash:TiFlash 是一類特殊的存儲節(jié)點。和普通 TiKV 節(jié)點不一樣的是,在 TiFlash 內(nèi)部,數(shù)據(jù)是以列式的形式進行存儲,主要的功能是為分析型的場景加速。
三、集群信息
(一)Store情況

192.168.2.81:20160 ---> id=4
192.168.2.82:20160 ---> id=5
192.168.2.83:20160 ---> id=1
192.168.2.81:20161 ---> id=6247
192.168.2.82:20161 ---> id=6246
192.168.2.83:20161 ---> id=6248
(二)測試表db 1.sbtest 1的region分布情況

查看各4個region的分布情況




Region 5037 ---> leader:4 follower:1,5
Region 5015 ---> leader:6247 follower:1,4
Region 5029 ---> leader:6248 follower:4,6246
Region 6001 ---> leader:4 follower:1,6246
(三)模擬tikv出現(xiàn)故障
當(dāng)模擬192.168.2.81:20160和192.1-68.2.83:20160出現(xiàn)故障時,即store id為1和4時,Region 5037,Region 5015,Region 6001將同時失去兩個副本,包括leader和follower副本。
考慮到當(dāng)前環(huán)境是虛擬機多實例環(huán)境,我們需要通過關(guān)閉系統(tǒng)服務(wù)的自動拉起功能來模擬tikv故障環(huán)境。
具體操作如下:
打開文件/etc/systemd/system/tikv-20160.service。
將Restart的值修改為no,原來默認是always,即總是拉起服務(wù)的意思,改為no后,服務(wù)掛掉后不會自動拉起。
使修改生效,執(zhí)行命令systemctl daemon-reload。
殺掉192.168.2.81:20160和192.168.2.83:20160進程


查看集群狀態(tài),192.168.2.81:20160和192.168.2.83:20160出現(xiàn)Disconnected

這時候查看db1.sbtest1的表,出現(xiàn)tikv超時

使用 pd-ctl 檢查大于等于一半副本數(shù)在故障節(jié)點上的 Region,并記錄它們的 ID(故障節(jié)點為store id 1,4)
db1.sbtest1表上面包含這3個region
{"id":5015,"peer_stores":[4,1,6247]}
{"id":5037,"peer_stores":[4,1,5]}
{"id":6001,"peer_stores":[4,1,6246]}
(四)有損不安全恢復(fù)
現(xiàn)在由于三副本已損壞大于等于一半副本數(shù)的region,此時對應(yīng)表訪問不了,這時通過有損恢復(fù),但無法保證數(shù)據(jù)索引一致性和事務(wù)完整性。
在使用 Online Unsafe Recovery 功能進行數(shù)據(jù)有損恢復(fù)前,請確認以下事項:
離線節(jié)點導(dǎo)致部分數(shù)據(jù)確實不可用。
離線節(jié)點確實無法自動恢復(fù)或重啟。
檢查數(shù)據(jù)索引一致性
#若結(jié)果有不一致的索引,可以通過重命名舊索引、創(chuàng)建新索引,然后再刪除舊索引的步驟來修復(fù)數(shù)據(jù)索引不一致的問題

通過有損修復(fù)后,數(shù)據(jù)表可恢復(fù)讀寫
四、總結(jié)
1.在TiDB中,根據(jù)用戶定義的多種副本規(guī)則,一份數(shù)據(jù)可以同時存儲在多個節(jié)點中,這樣可以確保在單個或少數(shù)節(jié)點暫時離線或損壞時,讀寫數(shù)據(jù)不會受到任何影響。然而,當(dāng)一個Region的多數(shù)或全部副本在短時間內(nèi)全部下線時,該Region將變?yōu)闀簳r不可用的狀態(tài),無法進行讀寫操作。
2.一旦執(zhí)行了unsafe recovery,所指定的節(jié)點將被設(shè)為 Tombstone 狀態(tài),不再允許啟動,執(zhí)行過程中,所有調(diào)度以及 split/merge 都會被暫停,待恢復(fù)成功或失敗后自動恢復(fù)。
