PostgreSQL邏輯複製解密

来源:https://www.cnblogs.com/Jcloud/archive/2022/09/21/16714652.html
-Advertisement-
Play Games

在數字化時代的今天,我們都認同數據會創造價值。為了最大化數據的價值,我們不停的建立著數據遷移的管道,從同構到異構,從關係型到非關係型,從雲下到雲上,從數倉到數據湖,試圖在各種場景挖掘數據的價值。而在這縱橫交錯的數據網路中,邏輯複製扮演著及其重要的角色。 讓我們將視角從複雜的網路拉回其中的一個端點,... ...


在數字化時代的今天,我們都認同數據會創造價值。為了最大化數據的價值,我們不停的建立著數據遷移的管道,從同構到異構,從關係型到非關係型,從雲下到雲上,從數倉到數據湖,試圖在各種場景挖掘數據的價值。而在這縱橫交錯的數據網路中,邏輯複製扮演著及其重要的角色。

讓我們將視角從複雜的網路拉回其中的一個端點,從PostgreSQL出發,對其邏輯複製的原理進行解密。

1 概念與原理

邏輯複製,是基於複製標識複製數據及其變化的一種方法。區別於物理複製對頁面操作的描述,邏輯複製是對事務及數據元組的一種描述。

圖-WAL數據流示例

如圖所示,物理複製的數據流是對tablespace/database/filenode文件的塊進行操作,而邏輯複製的內容是對元組進行描述。

接下來我們來看邏輯複製中的幾個概念:

複製槽

複製槽是記錄複製狀態的一組信息。由於WAL(預寫式日誌)文件在數據真正落盤後會刪除,複製槽會防止過早清理邏輯複製解析所需的WAL日誌。在邏輯複製中,每個插槽從單個資料庫流式傳輸一系列更改,創建複製槽需要指定其使用的輸出插件,同時創建複製槽時會提供一個快照。

輸出插件

輸出插件負責將WAL日誌解碼為可讀的格式,常用的插件用test_decoding(多用來測試),pgoutput(預設使用),wal2json(輸出為json)。PostgreSQL定義了一系列回調函數,我們除了使用上述插件,可以通過回調函數編寫自己的輸出插件。

圖-複製槽數據流

複製協議與消息

通過複製協議,我們可以從源端獲取WAL數據流。例如通過PSQL工具建議複製連接

psql "dbname=postgres replication=database"

開啟流式傳輸WAL

START_REPLICATION[ SLOT slot_name] [ PHYSICAL] XXX/XXX[ TIMELINE tli]

無論是物理複製,還是邏輯複製,使用PostgreSQL的發佈訂閱或者pg_basebackup搭建流複製,都是通過複製協議與定義的消息進行交互(物理複製和邏輯複製數據流內容不同)

圖- WAL數據流消息類型

圖-邏輯複製中的XLogData消息

工作流程

當我們瞭解了概念之後,來看一下整個解析的工作流程。由於WAL文件里一個事務的內容並不一定是連續的,所以需要通過Reorder後放在buffer中,根據事務ID組織成一條消息,COMMIT後發送給輸出插件,輸出插件解析後將消息流發送給目標端。

圖-邏輯解析工作流程

2 問題與演進

當我們掌握了邏輯複製的原理,計劃使用其構建我們的數據遷移應用之前,我們還有一些問題並沒有解決。讓我們來一起看看是什麼亟待解決的問題,以及我們如何進行處理。

問題一:Failover slot

為了高可用性,資料庫至少會存在一主一備的架構,當主庫故障進行高可用切換時,備庫卻沒有相應的複製槽信息,也就是缺少failover slot。這是由於保存slot信息的物理文件,未同步至備庫。那麼我們如何手動創建一個faliover slot呢?

1. 主庫創建複製槽,檢查備庫wal文件是否連續

2. 複製包含slot信息的物理文件至備庫,在pg_repslot目錄下

3. 備庫重啟,重啟後才可以看到複製槽信息,原因是讀取slot物理文件的函數StartupReplicationSlots只會在postmaster進程啟動時調用。

4. 定期查詢主庫slot狀態,使用pg_replication_slot_advance函數推進備庫複製槽

自此,我們在備庫上也有了相應的信息,手動實現了failover slot。PostgreSQL生態中著名的高可用軟體Patroni也是以這種方式進行了實現,區別隻是在Patroni查詢主庫slot狀態時將信息寫入了DCS中,備庫拿到DCS中的位點信息進行推進。

問題二:DDL同步

原生的邏輯複製不支持解析DDL語句,我們可以使用事件觸發器來進行處理。

1. 使用事件觸發器感知表結構變更,記錄到DDL_RECORD表中,並將該表通過邏輯複製進行發佈。

2. 接收端獲取到該表的數據變更,即可處理為相應DDL語句進行執行。

圖-事件觸發器實現DDL同步

問題三: 雙向同步

當數據遷移涉及雙向同步的管道時,例如想實現雙主雙寫,對資料庫同一對象進行操作,就會出現WAL迴圈。

圖-相同表雙向同步導致數據迴圈

部分DTS應用為瞭解決這個問題會創建輔助表,在事務中先對輔助表進行操作,通過解析到對輔助表的操作而得知該記錄是又DTS應用插入,從而過濾該事務,不再迴圈解析。PostgreSQL對事務提供了Origin記錄,無須輔助表,通過pg_replication_origin_session_setup函數或者發佈訂閱中的replorigin_create即可指定Origin ID。

指定Origin ID後,我們除了可以解析後通過DTS應用進行過濾,還也可以通過解析插件中的FilterByOriginCB回調函數在解析過程中過濾,這種方式減少了數據傳輸,效率更高。

圖-test_decoding中OriginFilter函數DEMO

其他問題:

除了以上三個問題,還有一些使用的問題或限制。這裡列出了一些,不再展開,僅簡要說明。

Toast處理:對於toast值(消息格式中可以判斷),我們在處理時一般使用占位符進行處理,接收端接收到占位符就不對這一列進行處理,雖然有些麻煩,但這也是在和傳輸toast值的方案中權衡的結果。

心跳錶:由於複製槽記錄的XMIN是全局的,當我們發佈的表一直沒有更新時,XMIN沒有推進導致WAL積壓,我們可以創建一張心跳錶,周期性寫入數據併發布,使XMIN進行推進。

大事務延遲: 根據前文提到的工作流程我們可以知道預設事務在COMMIT後才會進行解析,這對於大事務來說勢必會導致延遲,PG14版本提供了streamin模式進行解析,即事務進行中進行解析併發送至接收端。

3 應用與實踐

前兩節我們從原理及問題的角度對PostgreSQL進行瞭解密,接下來我們看如何通過我們掌握的邏輯複製原理,進行數據遷移的應用與實踐。

全量與增量同步

在真實的數據遷移場景中,大部分都是全量和增量都要同步的場景,並且我們打通了數據傳輸的通道後,也對這條通道的安全,效率,以及功能的擴展,例如清洗,脫敏等ETL能力提出了新的要求。我們先來看一下如果實現全量與增量的同步。

圖-數據流向示意圖

主要流程包括:

1. 創建複製槽並導出快照

2. 根據快照進行全量數據遷移

3. 根據複製槽進行增量數據的遷移

我們使用了PG資料庫或者消息隊列MQ作為數據代理,全量與增量解析可以同時進行,當全量數據處理完畢後,狀態機通知增量處理程式進行增量發佈。而對於代理中的數據,可以在解析後進行預處理。

自建實例遷移上雲實踐

最後和大家分享一個自建實例遷移上雲的實踐,該案例是將自建的PG10版本實例遷移至京東雲上的RDS PG 11版本,通過對增量數據的迴流以及數據校驗保證了數據安全與業務平穩切換。

圖-數據遷移上雲

DTS應用主要分為如下幾個階段:

1. 數據檢查階段: 檢查主鍵,許可權,配置

2. 數據遷移階段: 結構,存量,增量數據遷移,監控遷移狀態

3. 應用遷移階段: 切換功能變數名稱,引入流量

4. 回滾階段: 增量數據迴流,若出現問題可快速回滾。

 

作者:蔣帥


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.shell命令的執行機制:fork+exec執行命令(任何的shell都會執行) 2.shell中的用戶輸入處理 1 命令行參數:選項、參數 2 運行時輸入 3 read命令: 4 1.基本讀取、 5 2.超時處理-t選項、 6 3.隱藏方式讀取-s選項) 7 4.從文件中讀取 3.shell的 ...
  • 如果現在的我們離開了互聯網,生活會是什麼樣子? 互聯網++++,已經深刻滲透到人們的生活中。 不知道大家有沒有想過?每一個互聯網+結合的背後都是海量的存儲需求。你查看的每一個商品、組建的每一個戰隊、閱讀的每一篇文章,基於互聯網的每一個興趣愛好,都有它的key和value。 在 key-value 數 ...
  • 前言 在正式落地談技術之前,先花一些篇幅說說大數據技術的發展史。我們常說的大數據技術,其實起源於Google在2004年前後發表的三篇論文,分別是分散式文件系統GFS、大數據分散式計算框架MapReduce和NoSQL資料庫系統BigTable(如果大家需要可以留言給我,我可以專門解讀一下)。 一、 ...
  • 2022-09-21 (2)hash操作: ①設置多個hash值,(hmset): 查看說明: help hmset hmset person name A age 1 ②獲得多個hash值,(hmget): 查看說明: help hmget hmget person name age ③將hash ...
  • 摘要:帶你瞭解基於FusionInsight HD&MRS的5種kafka消費端性能優化方法。 本文分享自華為雲社區《FusionInsight HD&MRSkafka消費端性能優化方法》,作者: 穿夾克的壞猴子。 kafka消費端性能優化主要從下麵幾個方面優化: 1.介面使用方面優化: 舊版本hi ...
  • 摘要:RDS關係型資料庫是一種基於雲計算平臺的即開即用、穩定可靠、彈性伸縮、便捷管理的線上關係型資料庫服務。 本文分享自華為雲社區《一致性處理事務這下還是看RDS的吧【秋招特訓】》,作者:樣子的木偶。 什麼是RDS? RDS關係型資料庫是一種基於雲計算平臺的即開即用、穩定可靠、彈性伸縮、便捷管理的在 ...
  • 一、 登錄 1.1 登錄預設資料庫 首先切換到oracle用戶,用資料庫預設管理員登錄。 [root@tsm-zh01 ~]# su – oracle [oracle@redhat ~]$ lsnrctl start #開啟監聽 [oracle@tsm-zh01 ~]$ sqlplus / as s ...
  • 對於一個服務端開發來說 MYSQL 可能是他使用最熟悉的資料庫工具,然而,大部分的Java工程師對MySQL的瞭解和掌握程度,大致就停留在這麼一個階段:它可以建庫、建表、建索引,然後就是對裡面的數據進行增刪改查,語句性能有點差?沒關係,在表裡建幾個索引或者調整一下查詢邏輯就可以了,一條sql,MYS... ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...