全部產品
Search
文件中心

PolarDB:唯讀節點Online Promote

更新時間:Jul 06, 2024

唯讀節點Online Promote機制是PolarDB PostgreSQL版將唯讀備庫節點提升為主庫節點的一種Promote能力。

前提條件

支援的PolarDB PostgreSQL版的版本如下:

  • PostgreSQL 14(核心小版本14.5.1.0及以上)

  • PostgreSQL 11(核心小版本1.1.1及以上)

說明

您可通過如下語句查看PolarDB PostgreSQL版的核心小版本的版本號碼:

  • PostgreSQL 14

    select version();
  • PostgreSQL 11

    show polar_version;

背景資訊

PolarDB PostgreSQL版是基於共用儲存的一寫多讀架構,與傳統資料庫的主備架構有以下不同:

  • Standby節點:是傳統資料庫的備庫節點,有獨立的儲存,與主庫節點之間通過傳輸完整的WAL日誌來同步資料。

  • 唯讀節點:Replica節點,是PolarDB PostgreSQL版的唯讀備庫節點,與主節點共用同一份儲存,與主庫節點之間通過傳輸WAL Meta日誌資訊來同步資料。

傳統資料庫支援Standby節點升級為主庫節點的Promote操作,在不重啟的情況下,提升備庫節點為主庫節點,可以繼續提供讀寫服務,保證了叢集高可用的同時,也有效降低了執行個體的恢復RTO。

PolarDB PostgreSQL版同樣需要唯讀備庫節點提升為主庫節點的Promote能力,鑒於唯讀節點與傳統資料庫Standby節點的不同,PolarDB PostgreSQL版推出了一寫多讀架構下唯讀節點的OnlinePromote機制。

使用指南

使用pg_ctl工具對Replica節點執行Promote操作:

pg_ctl promote -D [datadir]

原理介紹

OnlinePromote原理觸發機制。

  • 觸發機制。

    PolarDB PostgreSQL版使用和傳統資料庫一樣的備庫節點Promote方法,觸發條件如下:

    • 調用pg_ctl工具的Promote命令,pg_ctl工具會向Postmaster進程發送訊號,接收到訊號的Postmaster進程再通知其他進程執行相應的操作,完成整個Promote操作。

    • recovery.conf中定義trigger file的路徑,其他組件通過產生trigger file來觸發。

    說明

    相比於傳統資料庫Standby節點的Promote操作,PolarDB PostgreSQL版Replica節點的OnlinePromote操作需要考慮以下幾個問題:

    • Replica節點OnlinePromote為主庫節點後,需要以讀寫入模式重新掛載共用儲存。

    • Replica節點會在記憶體中維護一些重要的控制資訊,這些控制資訊在主庫節點上會被持久化到共用儲存中。Promote過程中,這部分資訊也需要持久化到共用儲存。

    • Replica節點在記憶體中通過日誌回放得到的資料資訊,在OnlinePromote的過程中需要確認哪些資料可以寫入共用儲存。

    • Replica節點在記憶體中回放WAL日誌時,緩衝區淘汰方法和不刷髒的特性與主庫節點截然不同,OnlinePromote過程中應該如何處理。

    • Replica節點OnlinePromote過程中,各個子進程的處理過程。

  • Postmaster進程處理過程。

    1. Postmaster進程發現trigger file檔案或者接收到OnlinePromote命令後,進入OnlinePromote處理流程。

    2. 發送SIGTERM訊號給當前所有Backend進程。

      說明

      唯讀節點在OnlinePromote過程中可以繼續提供唯讀服務,但是唯讀資料不能保證是最新的。為了避免切換過程中從新的主庫節點讀到舊的資料,這裡需要先將所有的Backend會話斷開,等Startup進程退出後再開始對外提供讀寫服務。

    3. 重新以讀寫入模式掛載共用儲存。

      說明

      需要底層儲存提供相應的功能支援。

    4. 發送SIGUSR2訊號給Startup進程,通知其結束回放並處理OnlinePromote操作。

    5. 發送SIGUSR2訊號給Polar Worker輔助進程,通知其停止對於部分LogIndex資料的解析,因為這部分LogIndex資料只對於正常運行期間的Replica節點有用處。

    6. 發送SIGUSR2訊號給LogIndex BGW(Background Ground Worker)後台回放進程,通知其處理OnlinePromote操作。

    具體過程如下圖:Postmaster進程處理過程

  • Startup進程處理過程。

    1. Startup進程回放完所有舊主庫節點產生的WAL日誌,產生相應的LogIndex資料。

    2. 確認舊主庫節點最後一次的checkpoint在Replica節點也完成,目的是確保對應的checkpoint應該在Replica節點本地寫入的資料落盤完畢。

    3. 等待確認LogIndex BGW進程進入POLAR_BG_WAITING_RESET狀態。

    4. 將Replica節點本地的資料(如clog等)拷貝到共用儲存中。

    5. 重設WAL Meta Queue記憶體空間,從共用儲存中重新載入slot資訊,並重新設定LogIndex BGW進程的回放位點為其與當前一致性位點兩者的最小值,用來表示接下來LogIndex BGW進程從該位點開始新的回放。

    6. 將節點角色設定為主庫節點,並設定LogIndex BGW進程的狀態為POLAR_BG_ONLINE_PROMOTE,至此叢集可以對外提供讀寫服務。

    具體過程如下圖所示:Startup進程處理過程

  • LogIndex BGW進程處理過程。

    LogIndex BGW進程有自己的狀態機器,在其生命週期內,一直按照該狀態機器運行,具體每個狀態機器的操作內容如下:

    參數

    說明

    POLAR_BG_WAITING_RESET

    LogIndex BGW進程狀態重設,通知其他進程狀態機器發生變化。

    POLAR_BG_ONLINE_PROMOTE

    讀取LogIndex資料,組織並分發回放任務,利用並行回放進程組回放WAL日誌,該狀態的進程需要回放完所有的LogIndex資料才會進行狀態切換,最後推進後台回放進程的回放位點。

    POLAR_BG_REDO_NOT_START

    表示回放任務結束。

    POLAR_BG_RO_BUF_REPLAYING

    Replica節點正常運行時,進程處於該狀態,讀取LogIndex資料,按照WAL日誌的順序回放一定量的 WAL日誌,每回放一輪,便會推進後台回放進程的回放位點。

    POLAR_BG_PARALLEL_REPLAYING

    LogIndex BGW進程每次讀取一定量的LogIndex資料,組織並分發回放任務,利用並行回放進程組回放WAL日誌,每回放一輪,便會推進後台回放進程的回放位點。

    具體過程如下圖所示:

    LogIndex BGW進程處理過程

    LogIndex BGW進程接收到Postmaster的SIGUSR2訊號後,執行OnlinePromote操作的流程如下:

    1. 將所有的LogIndex資料落盤,並切換狀態為POLAR_BG_WAITING_RESET

    2. 等待Startup進程將其切換為POLAR_BG_ONLINE_PROMOTE狀態。

      • Replica節點在執行OnlinePromote操作前,後台回放進程只回放在buffer pool中的頁面。

      • Replica節點處於OnlinePromote過程中時,鑒於之前主庫節點可能有部分頁面在記憶體中,未來得及落盤,所以後台回放進程按照日誌順序回放所有的WAL日誌,並在回放後調用MarkBufferDirty,標記該頁面為髒頁,等待刷髒。

      • 回放結束後,推進後台回放進程的回放位點,然後切換狀態為POLAR_BG_REDO_NOT_START

  • 刷髒控制。

    每個髒頁都帶有一個Oldest LSN,該LSN在FlushList裡是有序的,目的是通過這個LSN來確定一致性位點。

    Replica節點在OnlinePromote過程後,由於同時存在著回放和新的頁面寫入,如果像主庫節點一樣,直接將當前的WAL日誌插入位點設為Buffer的Oldest LSN,可能會導致:比它小的 Buffer 還未落盤,但新的一致性位點已經被設定。

    所以Replica節點在OnlinePromote過程中需要面對兩個問題:

    • 舊主庫節點的WAL日誌回放時,如何給髒頁設定Oldest LSN。

    • 新主庫節點產生的髒頁如何設定Oldest LSN。

    說明

    PolarDB PostgreSQL版在Replica節點OnlinePromote的過程中,將上述兩類情況產生的髒頁的Oldest LSN都設定為LogIndex BGW進程推進的回放位點。只有當標記為相同Oldest LSN的Buffer都落盤了,才將一致性位點向前推進。