分布式數(shù)據(jù)庫下誤刪表怎么恢復(fù)?
1、數(shù)據(jù)庫誤刪表恢復(fù)方案
應(yīng)用數(shù)據(jù)的完整性是保證應(yīng)用系統(tǒng)正常服務(wù)的重要基礎(chǔ),在實際應(yīng)用DDL部署過程或數(shù)據(jù)庫變更過程中,可能因為誤操作導(dǎo)致應(yīng)用關(guān)鍵表被誤刪除或truncate,影響業(yè)務(wù)的正常訪問。分布式數(shù)據(jù)庫中當(dāng)誤刪表時有不同的數(shù)據(jù)恢復(fù)方案:
- 基于數(shù)據(jù)庫備份+增量日志:該方案的前提是數(shù)據(jù)庫有一份全量的備份數(shù)據(jù),在這個全量備份數(shù)據(jù)的基礎(chǔ)之上應(yīng)用增量的數(shù)據(jù)庫日志,并且跳過誤操作的日志,進而完成表數(shù)據(jù)的恢復(fù)?;跀?shù)據(jù)庫備份的恢復(fù)方案在庫數(shù)據(jù)量大或者增量日志多的時候耗時較長,在這個恢復(fù)的過程中應(yīng)用是無法正常訪問的。
 - 基于閃回技術(shù):數(shù)據(jù)庫閃回技術(shù)是基于回收站和數(shù)據(jù)庫undo日志完成數(shù)據(jù)庫的恢復(fù)操作,undo數(shù)據(jù)用于記錄數(shù)據(jù)修改之前的狀態(tài)信息,數(shù)據(jù)庫會將這部分數(shù)據(jù)寫入undo段中用于回滾事務(wù),或者發(fā)生錯誤時恢復(fù)數(shù)據(jù)到修改前的狀態(tài)。對于誤刪表等操作,數(shù)據(jù)庫中實際上是一個rename操作,將表移動到回收站,只要回收站中的空間足夠且未被清理,就可以使用閃回刪除來恢復(fù)被刪除的表。
 - 基于延遲復(fù)制方案:延遲復(fù)制一般是在主備部署架構(gòu)的數(shù)據(jù)庫中通過備節(jié)點延遲復(fù)制主節(jié)點的數(shù)據(jù),當(dāng)主節(jié)點出現(xiàn)邏輯上的誤操作如誤刪表時,利用備節(jié)點延遲同步和跳過特定的誤操作事務(wù)日志來恢復(fù)數(shù)據(jù)。延遲復(fù)制通常是在生產(chǎn)集群之外再建一個單獨的最小化備集群,需要額外的部署成本,同時依賴數(shù)據(jù)庫廠商實現(xiàn)延遲復(fù)制并跳過特定的事務(wù)。
 
在誤刪表的故障場景下業(yè)務(wù)訪問誤刪除的表會報錯,業(yè)務(wù)對其它表的訪問仍然正常。下文將簡要介紹分布式數(shù)據(jù)庫下以上三種誤刪表操作下的數(shù)據(jù)恢復(fù)方法。
2、分布式數(shù)據(jù)庫下誤刪表恢復(fù)方法
2.1 基于備份+增量日志的恢復(fù)
數(shù)據(jù)庫的完整備份數(shù)據(jù)和增量日志是保證數(shù)據(jù)庫完整性的基礎(chǔ),一些重要的應(yīng)用系統(tǒng)每天會進行全量或增量的數(shù)據(jù)庫備份,在數(shù)據(jù)恢復(fù)的過程中首先基于這些備份數(shù)據(jù)恢復(fù)到備份時點的數(shù)據(jù),再通過增量日志追加的方式將數(shù)據(jù)恢復(fù)到PITR一致時間點。在誤刪表等特殊場景下,增量追加日志的時候需要將這一特殊的操作跳過,而在分布式數(shù)據(jù)庫中還需要恢復(fù)多個實例的數(shù)據(jù)和以及計算節(jié)點層的元數(shù)據(jù)信息。以下以GoldenDB分布式數(shù)據(jù)庫為例介紹這種誤刪表恢復(fù)方案的恢復(fù)過程。
圖片
1)恢復(fù)誤刪表的表結(jié)構(gòu)從保存的DDL中恢復(fù)出表結(jié)構(gòu)信息,用于后續(xù)表結(jié)構(gòu)恢復(fù)。
2)登錄到每個分片的主節(jié)點,解析binlog并獲取到刪表操作的gtidX信息
#執(zhí)行命令
$mysqlbinlog -vv mysql-bin.xxx |grep -i -B20 ‘drop table’找到類似如下信息:
SET @@SESSION.GTID_NEXT=’xxxx’/*!*/;
DROP TABLE xx.xx /*generated by server*/3)選取待恢復(fù)的備節(jié)點,并使用全量備份數(shù)據(jù)恢復(fù)備節(jié)點
##停止備節(jié)點
$dbmoni -stop
##使用restore命令恢復(fù)備節(jié)點
$restory.py --full_backup_filename=xx --my_cnf=xx.cnf --db_user=xx --db_password=xx4)追binlog到當(dāng)前狀態(tài),并跳過刪表的gtid檢查備節(jié)點狀態(tài),dbagent非啟動,并且數(shù)據(jù)庫實例是啟動的
$dbstate設(shè)置gtid_next并手動執(zhí)行空事務(wù),跳過drop table對應(yīng)的操作,gtid_next為之前解析binlog找到的
> set @@session_gtid_next=’xxxx’;
> begin;
> commit;啟動dbagent,將備機接入集群,開啟自動主從復(fù)制
##啟動備節(jié)點
$dbmoni -start5)檢查主備同步的狀態(tài),確認備機已追上主機
$show slave status \G
$show tables like ‘xx’此時備機中之前誤刪除的表數(shù)據(jù)已經(jīng)恢復(fù)。
6)發(fā)起主備切換,將恢復(fù)的備機作為主節(jié)點對外提供服務(wù)此時雖然主備切換成功,備節(jié)點作為新主,但是原主節(jié)點作為備機,和新主節(jié)點之間數(shù)據(jù)是不一致的,需要通過修復(fù)備機的方式恢復(fù)。
7)登錄Proxy節(jié)點,更新元數(shù)據(jù)信息。此時雖然數(shù)據(jù)節(jié)點已經(jīng)恢復(fù)了表數(shù)據(jù),但是在計算節(jié)點層沒有該表的元數(shù)據(jù)信息,需要通過恢復(fù)的元數(shù)據(jù)信息更新計算層的元數(shù)據(jù)。
8)修復(fù)其它備機狀態(tài)新發(fā)起全量備份,通過備份數(shù)據(jù)恢復(fù)其它備機。注意在主節(jié)點發(fā)起備份時候?qū)π阅軙胁糠謸p耗,比如響應(yīng)時間增加、IO影響等。
基于全量備份+增量日志的誤刪表恢復(fù)方法,在表數(shù)據(jù)恢復(fù)期間業(yè)務(wù)訪問這部分表會報錯,整個故障的RTO時間依賴于全量備份的恢復(fù)加上增量日志追平。在單主節(jié)點對外提供服務(wù)的時候,需要調(diào)整相關(guān)的配置,比如調(diào)整高低水位和主計數(shù)等,優(yōu)先可用性。
2.2 基于閃回空間的恢復(fù)
基于閃回空間的恢復(fù)是利用了回收站的機制,當(dāng)用戶執(zhí)行DROP表操作時,數(shù)據(jù)庫并不會立即從磁盤上刪除表的物理文件,而是將其移動到回收站中?;厥照局械膶ο罂梢员灰暈楸弧败泟h除”,即它們?nèi)匀淮嬖谟跀?shù)據(jù)庫中,但不再對用戶可見。多個分布式數(shù)據(jù)庫已支持閃回功能,比如TiDB、GaussDB、OceanBase、GoldenDB等。以GaussDB數(shù)據(jù)庫為例,回收站功能通過數(shù)據(jù)庫參數(shù)enable_recyclebin來啟用或禁用。回收站中對象的保留時間由參數(shù)recyclebin_retention_time來控制,超過該時間的對象將被自動清理。利用閃回恢復(fù)只需要秒級,并且恢復(fù)時間和數(shù)據(jù)庫大小無關(guān)。
#閃回被刪除的表
TIMECAPSULE TABLE { table_name } TO BEFORE DROP [RENAME TO new_tablename]
#閃回截斷的表
TIMECAPSULE TABLE { table_name } TO BEFORE TRUNCATE1)查看回收站,刪除的表被放入回收站
gaussdb=# SELECT * FROM gs_recyclebin;
 rcybaseid | rcydbid | rcyrelid |           rcyname            |    rcyoriginname     | rcyoperation | rcytype | rcyrecyclecsn |        rcyrecycletime         | rcycreatecsn | rcychangecs
n | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 | rcybucket 
-----------+---------+----------+------------------------------+----------------------+--------------+---------+---------------+-------------------------------+--------------+------------
--+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------+-----------
     18591 |   12737 |    18585 | BIN$42C23EB5699$9737$0==$0   | test            | d            |       0 |      79352606 | 2024-09-13 20:01:28.640664+08 |     79352595 |     7935259
5 |         2200 |       10 |             0 |          18585 | t             | t           | 225492       |         225492 |2)閃回drop表
gaussdb=# TIMECAPSULE TABLE test to before drop;查看表數(shù)據(jù)已經(jīng)恢復(fù)
閃回功能是一種強大的數(shù)據(jù)恢復(fù)技術(shù),在使用上受到閃回時間點和舊版本保留時間的限制。
- 閃回時間點限制:閃回功能只能回滾到開啟閃回功能后的某個時間點,且只能回滾到最近的一個事務(wù)提交點。這意味著,如果數(shù)據(jù)庫在開啟閃回功能之前已經(jīng)發(fā)生了錯誤操作,那么這些操作將無法通過閃回功能來恢復(fù)。
 - 舊版本保留時間:閃回功能依賴于舊版本的保留時間。如果舊版本數(shù)據(jù)被清理或刪除,那么將無法回滾到這些時間點。因此,用戶需要合理配置舊版本保留時間,以確保能夠回滾到所需的時間點。
 
另外閃回功能只支持部分DDL操作,比如drop表、truncate表等,對于誤刪庫、drop某個字段,以及因為硬件故障導(dǎo)致的數(shù)據(jù)不一致是無法恢復(fù)的。
2.3 基于延遲復(fù)制的恢復(fù)
基于延遲復(fù)制的誤刪表數(shù)據(jù)恢復(fù)方案在“國產(chǎn)分布式數(shù)據(jù)庫災(zāi)備高可用實現(xiàn)”一文中做過介紹,如OceanBase數(shù)據(jù)庫的物理備庫方案、GoldenDB數(shù)據(jù)庫的DRSP災(zāi)備集群方案。實現(xiàn)上主要是依賴分布式數(shù)據(jù)庫的災(zāi)備架構(gòu)建立一套延遲備庫集群,主備集群之間通過設(shè)置合理的延遲時間,當(dāng)主集群出現(xiàn)誤操作時,通過在備集群跳過對應(yīng)操作的事務(wù),完成主庫的數(shù)據(jù)同步,再切換到備集群對外提供服務(wù)。從實現(xiàn)機制上看和基于備份和增量日志的方式原理類似,少了全量備份數(shù)據(jù)恢復(fù)的動作,減少了恢復(fù)的RTO時間。相對應(yīng)的是部署建設(shè)成本的增加,需要在生產(chǎn)站點單獨再部署一套備庫集群用于故障場景下的數(shù)據(jù)恢復(fù),成本和收益的權(quán)衡,畢竟有更多的措施來預(yù)防這一類的故障場景。
2.4 不同恢復(fù)方案對比
總結(jié)以上三種針對誤刪表場景下的不同的數(shù)據(jù)恢復(fù)方案,在恢復(fù)RTO時間、技術(shù)復(fù)雜度、部署成本和使用限制等方面進行了對比如下:
方案  | 全量備份+增量日志  | 閃回空間  | 延遲復(fù)制  | 
恢復(fù)RTO  | 通過全量備份加上增量日志方式,數(shù)據(jù)恢復(fù)時間長  | 秒級恢復(fù)  | 依賴于增量日志同步回放時間,較長  | 
部署復(fù)雜度  | 方案成熟但操作復(fù)雜,數(shù)據(jù)恢復(fù)為數(shù)據(jù)庫的基本功能  | 操作簡單,依賴于數(shù)據(jù)庫本身的功能實現(xiàn)  | 不成熟并且操作復(fù)雜,依賴于數(shù)據(jù)庫的高可用架構(gòu)實現(xiàn)  | 
部署成本  | 低,基于現(xiàn)有的部署架構(gòu),不會增加額外的成本  | 一般,增加額外的存儲空間,并且開啟閃回功能會影響一定性能  | 高,需要額外部署一套  | 
技術(shù)限制  | 無  | 邏輯上恢復(fù),只支持部分DDL操作;保留時間上限制  | 延遲時間上限制  | 
- 恢復(fù)RTO
 
a.全量備份+增量日志:先基于全量備份恢復(fù)表,再加上增量日志追加方式,數(shù)據(jù)恢復(fù)時間長
b.閃回空間:支持秒級恢復(fù)
c.延遲復(fù)制:基于日志同步回放,時間較長
- 部署復(fù)雜度
 
a.全量備份+增量日志:PITR恢復(fù)是數(shù)據(jù)庫的基本功能,方案成熟但操作復(fù)雜,需要找到drop操作的gtid、指定備機跳過gtid先恢復(fù)備機
b.閃回空間:操作簡單,依賴于數(shù)據(jù)庫本身的功能實現(xiàn)
c.延遲復(fù)制:不成熟并且操作復(fù)雜,依賴于數(shù)據(jù)庫的高可用架構(gòu)實現(xiàn)
- 部署成本
 
a.全量備份+增量日志:低,基于現(xiàn)有的部署架構(gòu),不會增加額外的成本
b.閃回空間:一般,增加額外的存儲空間,并且開啟閃回功能會影響一定性能
c.延遲復(fù)制:高,需要額外部署一套備集群
- 技術(shù)限制
 
a.全量備份+增量日志:無
b.閃回空間:邏輯上恢復(fù),只支持部分DDL操作;保留時間上也存在限制
c.延遲復(fù)制:延遲時間設(shè)置上有限制,超過時間后已經(jīng)同步到備機
在實際應(yīng)用過程中,如果數(shù)據(jù)庫本身支持閃回功能優(yōu)先使用該恢復(fù)方案,能夠滿足快速的RTO恢復(fù)要求。在閃回功能不成熟或沒有該功能時,選擇全量備份的恢復(fù)方式,方案成熟并且通用性強。
參考資料
- GoldenDB分布式數(shù)據(jù)庫備份恢復(fù)
 - GaussDB數(shù)據(jù)庫閃回恢復(fù)
 - 國產(chǎn)分布式數(shù)據(jù)庫延遲復(fù)制實現(xiàn)
 















 
 
 













 
 
 
 