最近在進行核心業務系統的切換演練測試,就在想一個最佳的分布式數據庫高可用部署方案是如何保證數據不丟、系統可用的,做到故障時候可切換、可回切,并且業務數據的一致性。本文簡要介紹了OceanBase數據庫和GoldenDB數據庫在災備高可用的部署方案,以參考。
在生產環境數據庫相關的變更操作時,可能因為DML或DDL操作導致數據被篡改或者表結構不可逆,此時需要數據庫提供一種高可用機制和能力恢復到變更前的時點,以保證業務的連續性。主要有兩種思路,一種是閃回功能將數據恢復到變更操作的時點;另一種是延遲復制,備節點和主節點之間的數據復制設置一個延遲時間,主節點出現邏輯上的誤操作時,利用備節點延遲同步來恢復數據。
1)閃回功能
國產數據庫中很多已支持閃回功能,比如TiDB、GaussDB、OpenGauss、OceanBase等。以GaussDB為例在Ustore引擎中閃回功能,通過參數enable_recyclebin控制回收站的實時打開和關閉。并通過recyclebin_retention_time參數設置回收站對象保留時間,超過該時間的回收站對象將被自動清理。
2)延遲復制
在主備部署架構的數據庫中,基本都能實現延遲復制功能,像MySQL、OpenGauss這樣的單實例數據庫。比如在OpenGauss數據庫中的延遲復制,允許將回放延時一段指定的時間后進行回放,提供一份可查詢一段時間之前的數據副本;在MySQL數據庫中通過MASTER_DELAY來配置主節點和備節點的復制延遲。
在集中式主備架構的延遲復制實現基礎之上,分布式數據庫在架構上如何實現延遲復制以保證高可用。對于分布式架構的難點之一是如何確保故障場景下各個分片之間的數據一致性。對于國產分布式數據庫OceanBase、GoldenDB以及TiDB等,已經有不少成熟的方案。本文將重點介紹OceanBase數據庫的物理備庫方案和GoldenDB數據庫的DRSP災備集群方案,不僅僅實現了延遲復制功能,而且滿足災備切換方案的多樣性和靈活性,如異地災備方案和孤島驗證方案。
1、OceanBase數據庫物理備庫方案
OceanBase數據庫支持多副本的高可用容災方案,同時也支持基于物理備庫的準實時熱備份方案。當生產主庫出現故障時,備庫可以接管服務,最大限度降低服務停機時間,減少可能帶來的數據損失。從V4.1.0版本開始,OceanBase數據庫按照租戶粒度提供物理備庫能力,分為主租戶和備租戶:主租戶是業務運行的租戶,提供完整的數據庫服務能力;備租戶只提供容災和只讀服務能力。
OceanBase的物理備庫主要通過日志傳輸服務和日志存儲服務來完成日志的傳輸及存儲,并通過日志回放服務來保證主備租戶數據的一致,其中:
- 日志傳輸服務在主租戶和備租戶之間實時同步 Redo 日志。當前OceanBase數據庫物理備庫僅提供異步同步模式。
- 日志存儲服務為物理備庫提供高可用、高可靠的日志存儲和讀寫能力。
- 備租戶寫入日志存儲服務的日志會通過日志回放服務實時或延后地應用到內存的MemStore之中,以保證主租戶和備租戶的數據完全一致。
1.1 物理備庫的部署方案
OceanBase物理備庫的部署方案中,可以按照集群中主租戶和備租戶進行不同的組合,主租戶和備租戶可以在同一個集群中,也可以在不同的集群中。典型的部署方案有幾種:
- 集群中僅有主租戶或備租戶:包括多個OceanBase集群,業務租戶在一個集群,備租戶在另外一個集群,中間采用異步復制的方式,滿足異地容災的高可用需求;
- 集群中既有主租戶又有備租戶:多中心多活的部署架構,不同地域之間的集群互為主備;
- 主租戶和備租戶在同一個集群中:主備租戶在同一個集群中進行管理,適用于數據庫變更或升級的場景,又不需要增加額外的管理集群資源。
第三種部署架構適合租戶在升級或者數據庫變更操作前,在備租戶中保留一份數據庫快照,將被租戶的同步暫停。業務在主租戶上進行升級變更等操作,如果變更異常,將備租戶切換為主租戶對外提供服務,以保證業務的連續性。
1.2 物理備庫的日志傳輸
物理備庫通過日志傳輸服務在主租戶和備租戶之間實時同步Redo日志,備租戶既可以通過主租戶的日志歸檔來獲取日志,也可以通過網絡直連主租戶所在的集群來獲取日志。
- 基于日志歸檔的物理備庫:主租戶開啟日志歸檔將日志歸檔到目標存儲(OSS/NFS)中,備租戶恢復歸檔日志實現數據同步;需要主租戶和備租戶開啟歸檔模式。
- 基于網絡傳輸的物理備庫:備租戶直接通過網絡連接主租戶或其他備租戶讀取日志,類似于MySQL數據庫的復制方式。
在基于網絡傳輸的部署模式下,備租戶從主租戶讀取的日志,既可以是主租戶的在線日志,也可以是主租戶的歸檔日志。同時這種模式下支持集群級別的限速。
1)暫停或開啟日志同步
#登錄備租戶或所在集群的sys租戶,執行命令暫停租戶日志同步
ALTER SYSTEM RECOVER STANDBY [TENANT = tenant_name] CANCEL ;
#登錄備租戶或所在集群的sys租戶,執行命令開啟租戶日志同步
ALTER SYSTEM RECOVER STANDBY [TENANT = tenant_name] UNTIL UNLIMITED;
需要注意的是,暫停日志同步后,備租戶不會再從主租戶同步任何日志,盡量避免因暫停日志同步而導致的備租戶日志斷流。
2)查看日志同步進度
#執行SQL查看備租戶同步進度
SELECT TENANT_NAME, TENANT_ID, TENANT_ROLE, SCN_TO_TIMESTAMP(SYNC_SCN)
FROM oceanbase.DBA_OB_TENANTS WHERE TENANT_NAME = 'standby_tenant';
+----------------+-----------+-------------+----------------------------+
| TENANT_NAME | TENANT_ID | TENANT_ROLE | SCN_TO_TIMESTAMP(SYNC_SCN) |
+----------------+-----------+-------------+----------------------------+
| standby_tenant | 1004 | STANDBY | 2023-04-14 16:38:53.938774 |
+----------------+-----------+-------------+----------------------------+
1 row in set
3)設置同步限速
適用于集群之間備租戶同步限速
- standby_fetch_log_bandwidth_limit:用于設置備租戶所在集群中,可用于備租戶從主租戶或源端租戶進行日志同步的所有帶寬的總和。
- _server_standby_fetch_log_bandwidth_limit:用于設置備租戶所在集群的單個 OBServer 節點中,可用于備租戶從主租戶或源端租戶進行日志同步的帶寬。
1.3 日志存儲服務
OceanBase數據庫中日志存儲服務使用Paxos協議實現高可用,其中主租戶和備租戶中的日志存儲服務使用了不同的工作模式:
- APPEND模式:主租戶上使用APPEND模式。在該模式下,主租戶日志流的Leader會接收事務、DDL等上層模塊寫入的數據,并將這些數據在主租戶的多個副本之間使用 Paxos 協議進行同步并持久化。
- RAW_WRITE模式:備租戶上使用RAW_WRITE模式。在該模式下,備租戶日志流的Leader拒絕任何上層模塊直接寫入的數據,僅允許通過日志傳輸服務從主租戶同步物理日志,且這些物理日志的內容、LSN、SCN等信息均由主租戶生成。
在數據同步過程中,每一條日志都會在主租戶上生成一組唯一的LSN和SCN值。其中,LSN用于定位這條日志在存儲服務中的物理位置信息;SCN用于代表這條日志在存儲服務中的時序關系,上層服務可以使用SCN值對多個日志流之間的日志進行定序。
另外,無論是主租戶還是備租戶,在Paxos Group日志流副本中都會有LEADER和FOLLOWER兩種角色。對于主租戶,其業務數據是在日志流的Leader節點上寫入,再同步給所有Follower節點;對于備租戶,日志流的Leader節點主要負責通過日志傳輸服務從主租戶同步日志,并將同步過來的日志再同步給Paxos Group中的Follower節點。
1.4 主租戶和備租戶切換
OceanBase數據庫的主租戶和備租戶可以通過SwitchOver和Failover操作動態改變租戶角色:
- Switchover:在用戶計劃內對租戶角色進行變更。執行 Switchover操作后,主租戶會與對應的備租戶會交換租戶角色,整個過程數據不丟失RPO = 0,執行時間一般為秒級。
#將主租戶切換為備租戶
ALTER SYSTEM SWITCHOVER TO STANDBY TENANT = tenant_name;
#將備租戶切換為主租戶
ALTER SYSTEM SWITCHOVER TO PRIMARY TENANT = tenant_name;
- Failover:在主租戶出現無法恢復的故障時所做的切換行為。執行Failover操作后,對應的備租戶角色會變換成主。同時,如果對主租戶故障前一直正常同步的備租戶執行Failover操作,則執行Failover操作后,一般會產生百毫秒級別的數據損失,執行時間一般為秒級。
#將備租戶切換為主租戶
ALTER SYSTEM ACTIVATE STANDBY TENANT = tenant_name;
Failover操作需要在操作執行完成后達到數據一致的狀態,故系統會選擇所有日志流的同步位點中SCN最小的值作為Failover的執行位點。執行Failover操作后,租戶下的所有日志流都會統一回退到該位點。
2、GoldenDB數據庫
GoldenDB分布式數據庫除了支持同一套集群多中心的部署架構外,還支持DRSP的災備部署方案。DRSP高可用架構包括生產庫和災備庫/應急庫,生產庫是正常對外提供服務的GoldenDB集群;災備庫正常情況不提供服務,從生產庫復制數據的GoldenDB系統,用于提供災難、應急等場景下的緊急啟動能力,代替生產庫提供服務。如果所示,DRSP災備集群運行有三種模式:
- 數據同步模式:元數據、GTM數據、數據節點分別從源端生產庫同步到目標端災備庫,可通過配置延時時間讓同步過來的數據延時應用到災備庫上。
- 數據恢復模式:應用、檢查、修復同步過來的數據,使最終數據滿足分布式一致性要求。
- 服務模式:啟用災備集群,對外提供服務,,提供GoldenDB系統絕大部分正常功能。
這種部署方案的優點是生產集群和災備集群單獨維護,故障互不影響。相比較異地故障切換或者災備孤島演練,在切換方案上更為迅速靈活。相對應的缺點就是需要單獨維護兩套系統,增加了運維的復雜度。
2.1 不同模式切換
1)數據同步模式
正常情況下,生產庫處于服務模式,此時災備庫應當進入延時復制模式(sync模式)接入生產庫。執行以下命令進入延時復制模式:
sh AllControl.sh -sync 1 -delay_time=
delay_time填寫延時應用的時間,單位為秒;如果不需要延時則填0
2)數據恢復模式
當生產庫發生故障或誤操作時,需要切換至災備庫進行接管,此時災備庫應當先進入數據恢復模式(recovery模式)恢復數據,再切換至服務模式對外提供服務。
- 命令退出延時復制模式
sh AllControl.sh -stopsync 1
- 指定需要回放到的時刻或GTID
#指定回放時刻
sh bat_mod_relaytime.sh 1 "RELAY_TIME"
#回放所有relay log
sh bat_mod_relaytime.sh 1 ""
#指定回放的GTID
三種場景中記錄下的回放時刻在回切時會作為生產庫元數據同步的起始時刻
- 進入災備庫數據恢復模式
sh AllControl.sh -recover 1
3)數據服務模式
數據恢復完成后,通過以下步驟切換至服務模式
sh AllControl.sh -service 1
當災備庫不再需要服務時,執行命令退出服務模式
2.2 災備庫回切
當災備庫服務一段時間以后,需要將服務回切至生產庫,要求生產庫數據和災備庫基本一致。此時可以將生產庫和災備庫角色對調,將生產庫接入當前已服務的災備庫中,從災備庫同步數據。停止災備庫業務,等待生產庫同步數據完成后啟動生產庫,由生產庫提供服務。
- 登錄生產庫某一管理節點服務器,將生產庫退出服務模式
sh AllControl.sh -stopservice 1
- 生產庫集群1停服
sh start_stop_service.sh -stop_dbproxy 1
- 修改元數據同步起始時刻,回滾生產庫集群至一致性時刻,并進行分片數據一致性校驗
sh bat_mod_laststamp.sh "1" "2024-01-01 10:00:00"
其中1為集群ID,"2024-01-01 10:00:00"為元數據同步起始時刻,該時刻根據災備庫進行恢復時設置的恢復時間確定
- purge生產庫完成回滾且主備數據一致的分片
- 生產庫進入延時復制模式
sh AllControl.sh -sync 1 -delay_time=0
- 逐步停掉災備庫上的業務,讓proxy上所有事務都提交。禁用災備庫集群1,停止該集群綁定的所有proxy進程。
- 生產庫退出復制模式并進入服務模式
- 災備庫退出服務模式并進入延遲復制模式
2.3 災備演練場景回切
在災備孤島等演練場景下,災備站點和生產站點孤島隔離,演練結束后,需要將災備站點的數據回滾到演練前的時刻。GoldenDB數據庫的DRSP復制方案中提供了閃回功能,將數據閃回到災備庫恢復之后,提供服務之前的一個時刻。
- 快照持久化:針對災備庫,在災備庫執行服務模式起連接實例之前,將當前災備庫的快照點持久化到RDB庫。為后續的閃回提供服務。
- 閃回:將災備庫服務模式下產生的業務恢復至快照點,方法是執行性反向sql,所以災備庫服務期間,如果有DDL,可能會失敗。此時根據實際情況,看是否需要備份恢復。
- 備機回放檢查:閃回功能是通過在主機上執行反向sql來完成回滾操作,所以備機可以以同步回放的方式進行數據同步。所以需要所有備機回放完全完成才可以下一步的purge。
- purge:閃回通過反向sql實現的,所有本身的災備庫gtid_set會一直增加,所以需要通過purge操作將gtid_set恢復至快照時刻。
以上是OceanBase數據庫和GoldenDB數據庫延遲復制和災備的高可用實現方案簡單總結,實際實現過程更為復雜,以官方的文檔材料為準。
參考資料:
- https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000818706
- GoldenDB數據庫DRSP雙集群同步