阿里云:PolarDB for PostgreSQL 開源必讀手冊(125頁).pdf

編號:106490 PDF 125頁 45.47MB 下載積分:VIP專享
下載報告請您先登錄!

阿里云:PolarDB for PostgreSQL 開源必讀手冊(125頁).pdf

1、封面頁(此頁面將由下圖全覆蓋,此為編輯稿中的示意,將在終稿 PDF 版中做更新)目錄 開源 PolarDB for PostgreSQL 架構介紹.4 PolarDB 安裝與配置.14 PolarDB 數據庫結構.21 Foreign Data Wrappers(FDW)使用介紹.35 用戶和權限管理.47 VACUUM 處理.65 緩沖區管理器.75 備份與恢復.82 共享存儲原理與實踐.95 云原生 HTAP.108 最佳場景實踐與壓測.120 開源 PolarDB for PostgreSQL 架構介紹 4 開源 PolarDB for PostgreSQL 架構介紹 一、PolarDB

2、 總體架構設計 傳統數據庫的部署方式,有主庫、備庫和 Standby,主備庫之間通過流復制進行同步。節點擴展時,需要將數據全部進行復制,速度極慢。另外,主備之間復制一般使用異步復制,可能存在數據丟失。主備之間存在延遲,因此可用性較差。此外,隨著副本數的增加,存儲成本呈線性增加。針對以上問題,PolarDB 實現了計算存儲分離架構。開源 PolarDB for PostgreSQL 架構介紹 5 在 PolarDB 架構中,共有三個節點,其中一個讀寫節點,兩個只讀節點。存儲數據時,通過網絡存儲到后端存儲池。該架構具有四個優勢:第一,擴展性較好。計算能力不足時,只需簡單操作即可增加計算節點。因為數

3、據存儲在共享存儲上,無需再做一次復制。且計算節點無狀態,擴展快。而當計算資源過多時,可以將三個節點迅速縮為兩個節點。第二,成本低。多個計算節點共享一份數據,存儲成本顯著下降。傳統數據庫有 N個備庫,數據需要復制 N 份。而存儲計算分離架構下,數據只需在共享存儲上存儲一份即可。第三,易用性。存儲計算分離架構的存儲池技術相對較成熟,保證了數據不會丟失。計算側每一個節點都能看到完整的數據庫狀態,使用體驗接近于單機數據庫。第四,可靠性。由于共享存儲具備了三副本以及秒級備份等特性,其可靠性也得到了保障。PolarDB 計算存儲分離的模塊棧分為四層。開源 PolarDB for PostgreSQL 架構

4、介紹 6 事務層:除了原生事務,還實現了 CSN 快照。日志層:主庫將 WAL 日志寫到共享存儲上,備庫無需再做一次流復制,從共享存儲上讀取日志即可。此外還實現了 lazy 回放、并行回放和 LogIndex 等核心數據結構。緩存層:實現了常駐 BufferPool,節點重啟時,buffer 數據無需重新預熱。另外,實現了多版本頁面,解決了 fullpage 問題。存儲層:實現了 Direct IO、數據預讀、預擴展以及抽象了 PolarVFS 文件系統接口。PolarDB 除了實現計算存儲分離架構,還實現了 HTAP 架構。PolarDB1.0 計算存儲分離時,可以通過讀寫分離將 TP 事務

5、型查詢均勻地打散到不同節點上。但該架構在處理 AP 型查詢時存在一些問題,因為查詢只能在計算節點上處理,無法發揮多個計算節點的能力。開源 PolarDB for PostgreSQL 架構介紹 7 因此,PolarDB 在存儲計算分離架構上進一步實現了 HTAP 架構。如圖中所示,在計算層實現了分布式并行計算引擎。任何一個計算節點均支持單機查詢引擎,也支持分布式并行計算查詢引擎。如上圖,最左側節點可用于處理單機 TP 型查詢,用戶可將業務中所有 TP 查詢、點查發送到該節點。同時,分析性查詢可利用多個計算節點的特性來完成計算(上圖中的只讀節點),四個節點基于 MPP 工作原理。最終,我們實現了

6、一套系統,既可以做單機點查、點寫,也可以做多機并行計算引擎處理 AP 分析。以上架構實現了一體化存儲,TP 和 AP 共享一份數據,用戶將 TP 數據寫到共享存儲,AP 做分析時可以實現毫秒級的數據新鮮度。傳統的解決方案下,TP 庫到 AP 庫之間的復制延遲非常長。另外,使用一份存儲也減少了存儲成本。其次,該架構將 TP 和 AP 做了物理隔離,可以將部分節點配置為負責處理 TP 查詢,單機執行;然后將其他節點部署為分布式 MPP 執行,實現了 TP 和 AP 的物理隔離,甚至可以實現不同業務域運行在不同計算節點上,避免 AP 查詢對 TP 查詢的影響。另外,該架構也具備了 Serverles

7、s 彈性擴展能力,任何 RO 節點均可以發起 MPP 查詢。傳統 MPP 查詢中存在一個協調節點,而 PolarDB 里每個節點均可看到所有數 開源 PolarDB for PostgreSQL 架構介紹 8 據以及元數據,所有節點本質上是對等的,因此任何節點都可以作為 MPP 查詢的協調節點。同時,實現了SQL級別調整單機執行并行度以及SQL級別調整MPP執行節點范圍。這意味著計算能力不足時,可以迅速增加計算節點。因此新增節點可以直接訪問共享存儲,對計算能力做擴展時,無需對數據做重分布。傳統 MPP 統在新增節點時需要對數據做重分布,過程相當漫長,而 PolarDB 幾乎可以實現秒級生效。另

8、外,如果存儲容量不足需要增加機器,也無需再做擴容,因為PolarDB底層為分布式存儲,存儲池化后容量按需分配,可以認為容量無限大,無需擔心存儲容量不足的問題。HTAP 架構內置了兩個優化器,其一為傳統內置優化器,用于處理單機查詢。其二為GPORCA 優化器,用于處理分布式查詢。執行器層引入了大量算子。除了單機執行引擎所需要的算子之外,還需要對以上算子做并行化改造,比如支持 Shuffle 節點、支持對順序掃描節點的并行化操作。事務層,PolarDB HTAP 完整兼容事務,執行 MPP 時完備兼容事務的可見性級別。PolarDB HTAP 實現了 SQL 全兼容,做了大量工作實現 SQL 特性

9、。開源 PolarDB for PostgreSQL 架構介紹 9 PolarDB 除了支持存儲計算分離和 HTAP 架構,還支持三節點高可用架構。該架構為基于 X-Paxos 做流復制,同時可以將 PolarDB 部署在本地盤,在可用區內部通過X-Paxos 實現了低延遲系統。由于接入了 X-Paxos 協議,在某個節點宕機時可自動選擇 leader 節點、自動做恢復、自動做集群節點變更。同時,借助 DataMax 既可以支持日志+存儲的部署方式,也支持僅部署日志的方式,實現兩地三中心的部署。如圖所示,可以將可用區域 1 中的日志通過異步或同步方式復制到 Log Syncer 進程,該進程在

10、本地盤只存儲了日志,并不存儲數據,同時將WAL 日志向下游做復制,復制到另一可用區。從而既保證了可用性,又從成本上得到了進一步控制。開源 PolarDB for PostgreSQL 架構介紹 10 PolarDB 支持存儲計算分離架構、HTAP 架構以及三節點高可用架構,可以通過不同的配置文件部署成不同的方式,三個架構為正交關系。如上圖左側,可以是云原生和 HTAP 混合使用的方式,業務可以根據自己的需求將TP 和 AP 流量分別發送到不同的計算節點,且只需一份存儲。如上圖右側,可以借助X-Paxos將PolarDB以本地盤的方式進行部署,有一個leader和兩個 follower,可實現高

11、可用。同時,本地盤的方式也可以支持 HTAP 的業務負載,比如可以將 TP 查詢發送到 leader 節點上,同時將 AP 查詢發送到 follower 上。且多個 follower 節點和 leader 節點可以組織成分布式查詢,解決了傳統 TP 數據庫主備方式做分析時計算能力擴展的問題。二、PolarDB 企業級特性 PolarDB 還實現了企業級特性。架構方面,支持存儲計算分離架構、HTAP 架構以及三節點高可用架構。開源 PolarDB for PostgreSQL 架構介紹 11 1.性能方面 實現了 CSN 快照用于解決單核場景下,隨著核數增加其性能線性擴展的問題。實現了 WAL

12、Pipeline 功能,加速 WAL 日志的寫入,提高寫入吞吐量。實現了預讀和預擴展功能,一般做分析查詢時需要大量掃描,而預讀功能可盡可能地發揮共享存儲大帶寬的特性。實現了 RelSizeCache,查詢時首先需要得到文件大小,此功能實現了對文件的元數據做緩存。實現了 CLOG 優化以及 FullPageWrite 優化,主要為通過 LogIndex 以及頁面多版本徹底避免 FullPage 的問題。FullPage 在 PolarDB 里有兩種解法。?解法一:如果共享存儲提供了 8k 或 8k 以上的原子寫,可直接將 FullPage關閉。因為共享存儲是軟件定義的存儲,其原子寫可以大于硬件的

13、頁面單元。?解法二:如果共享存儲原子寫在 8k 以下,可以使用頁面多版本,將 FullPage內容從 WAL 日志剝離,即可大幅減少 WAL 日志容量。2.高可用方面 實現了 DataMax,DataMax 指 logger 節點,可以通過配置文件將 PolarDB 部署成只存儲 WAL 日志,不存儲數據頁面。再配合 X-Paxos 即可實現兩地三中心的部署架構。實現了 Online Promote,原生做 HA 切換時需要重啟,而我們通過 Online Promote 實現了在線將備庫切換為主庫,進程無需重啟。實現了延遲回放和并行回放,能夠降低主備之間的復制延遲,經過測試,在高壓力情況下,可

14、實現毫秒延遲。實現了常駐 BufferPool,數據庫 BufferPool 做重啟時,BufferPool 的內存會丟失,導致數據庫重啟后需要花費長時間做預熱。而常駐 BufferPool 將 BufferPool內容剝離,放至共享存儲,不會隨著進程重啟被銷毀,維護了 buffer 的可用性。實現了 Replication Slot 持久化功能,能夠避免備庫變成主庫之后 replication slot 的丟失。開源 PolarDB for PostgreSQL 架構介紹 12 實現了算子級別內存控制。執行分析性查詢時,某些算子會占用大量內存,導致內存膨脹,最終導致 OOM。而算子級別內存控

15、制可以精細控制每個算子的內存使用上限。安全方面,實現了 TDE 透明加密功能。支持 AES 128、256 以及國密 SM4 算法。三、PolarDB 開源社區 PolarDB 在 2021 年云棲大會之前對所有內核代碼全部做了開源,包括 PolarDB 內核、PolarDB 分布式文件系統以及 PolarDB 云管控,我們始終堅持 100%兼容社區的 PostgreSQL。開源代碼與公有云上代碼一致,經過了云上客戶以及內部測試人員的大量驗證,代碼質量極高,用戶可以直接將其部署在自己的生產環境中使用。開源 PolarDB for PostgreSQL 架構介紹 13 PolarDB 在開源的同

16、時,還提供了豐富的文檔和視頻資料,比如整體架構文檔介紹、核心功能原理解析、快速入門文檔以及每周的釘釘群 PolarDB 內核原理解析。PolarDB 安裝與配置 14 PolarDB 安裝與配置 PolarDB 的安裝軟件在 GitHub 上,因此安裝前需要先注冊 GitHub 賬號。虛擬機安裝 PolarDB 時,為了能夠更好地繼承 postgres 數據庫的使用習慣,建議使用postgres用戶進行安裝,并為該用戶賦予sudo和工作目錄權限。安裝完以后,執行上圖中的代碼。PolarDB 安裝與配置 15 此時需要注意目錄的權限。創建用戶時,默認會在 home 目錄建 postgres 目錄

17、,確認目錄的屬主為 postgres。執行上圖命令,繼承環境變量,配置 sudo 使用資源的限制。下載安裝 GitHub 軟件,并在本地添加登錄的用戶名和郵箱,最后通過 git config 命令查看是否添加成功。添加成功顯示的結果 在 GitHub 上添加 SSH 需要 RSA 密鑰。PolarDB 安裝與配置 16 密鑰在 Linux 主機上產生,執行上圖命令,其中 為注冊郵箱名。產生RSA 密鑰后,需要將密鑰粘貼到 GitHub 配置里。如上圖所示,選中的即為 RSA 密鑰。PolarDB 安裝與配置 17 登錄 GitHub,點擊進入 Settings。點擊 SSH and GPG k

18、eys。輸入 rsa 以及密鑰,點 Add SSH key。PolarDB 安裝與配置 18 下 載 軟 件。下 載 完 以 后 進 入 到 PoalarDB-for-PostgreSQL 目 錄 下 執 行sudo./install_dependencies.sh 腳本,用于下載 PolarDB 在安裝過程中需要的系統軟件包。下載完后進行編譯。需要通過$source/etc/bashrc 更新環境變量,否則編譯可能會報錯。然后進入目錄,執行編譯,系統會初始化一個實例。PolarDB 安裝與配置 19 部署完以后,通過以上命令進行實例檢查和測試,確保部署成功。返回上圖結果則說明部署成功。Pol

19、arDB 安裝與配置 20 為了方便后面的使用,還需在 postgres 用戶下添加環境變量。添加 PG_HOME 以及 PGDATA 的路徑,并聲明端口。其中 tmp 為阿里開發的文件系統,可以理解為共享存儲,可以被多個節點訪問。這也意味著節點啟動實例時,無需復制拷貝,直接訪問節點上的數據即可。然后配置用戶名、訪問的主機以及數據庫。完成以上配置后,通過$psql 即可登錄到 PolarDB 數據庫。如上圖所示,實例一級對本地的用戶登錄是信任的,因此登錄時無需提供密碼。PolarDB 數據庫結構 21 PolarDB 數據庫結構 PolarDB 由眾多數據庫組成,因此稱為數據庫集群,每個數據庫

20、下存放各自的對象,對象包括表、索引、視圖、存儲過程、序列等。登錄到數據庫以后,可以通過l 查看數據庫信息。PolarDB 數據庫結構 22 PolarDB 提供了兩種 SQL 語句,一種是標準的 SQL 語句,另一種是 PSQL。PSQL 使用 l 來代替 select pg_database 語句??梢酝ㄟ^?查看 PSQL 提供的所有命令。PolarDB 管理對象時通過 oid(對象標識符)進行管理,它與數據庫物理結構的名字一一對應,數據庫 oid 和堆表 oid 分別存儲在 pg_database 和 pg_class。進行數據庫訪問時,PGDATA 變量指定了整個數據庫的基本位置。下面的

21、 base 目錄是所有數據庫的副目錄,其下的子目錄都以數字命名,與每個數據庫的 OID 對應。PolarDB 數據庫結構 23 比如查找當前數據庫的物理位置,需要先找到 PGDATA 目錄所在。查看 base 目錄,即可看到它以數字命名的子目錄。PolarDB 數據庫結構 24 子目錄名稱與數據庫創建目錄的 OID(上圖)一致。上圖為 PGDATA 下不同目錄和文件的作用。pg_hba.conf 用于控制實例的訪問權限,可以在文件里定義哪一些主機可以訪問哪一 些 數 據 庫;postgresql.conf 是 PolarDB 數 據 庫 的 主 要 參 數 文 件,postgresql.aut

22、o.conf 是二進制的參數文件,兩者可以結合使用。PolarDB 代理啟動時先讀 postgresql.conf 文件,再讀 postgresql.auto.conf 文件。PolarDB 數據庫結構 25 上圖為數據庫集群布局的主要文件和子目錄。數據庫是 base 子目錄下的子目錄。初始化時,表的 OID 與數據文件名字一致,但 TRUNCATE、REINDEX 等操作會造成不一致。如上圖所示,查詢 sampletbl 表所在的數據文件。PolarDB 數據庫結構 26 首先,登錄到 sampledb。sampledb 數據庫的 OID 為 32768。到 sampledb 目錄下查找文件

23、 32769,可以發現實際的數據并沒有存放在該路徑下。因為 PolarDB 將數據存放的位置做了分流。真正的數據放在上圖路徑的 32768 子目錄下。PolarDB 數據庫結構 27 PolarDB 為了方便查找表的數據文件位置提供了查詢函數,如上圖。此處的 file-dio為 PolarDB 提供的共享存儲。隨著表的數據越來越多,文件尺寸超過 1GB 后,命名規則也會有所改變,會在原有名字后加上.1 以示區別。fsm(free space map)是空閑可用空間地圖。比如有多個數據塊,往表里插入數據時,需要明確哪個數據塊里有空間可用于存放新插入的數據,PolarDB 會先查看 fsm文件。v

24、m 是可見性地圖,主要用于對表空間進行整理,幫助 vacuum 時提高效率。數據文件的 fork 號為 0,空閑空間映射的 fork 號為 1,可見性地圖的 fork 號為 2。PolarDB 數據庫結構 28 PolarDB 也支持自建表空間(目前僅在企業版 PolarDB 支持)。創建新的表空間后,PGDATA 下的 pg.tblspc 目錄下存在與新建表空間名一致的目錄。它 是 一 個 指 針,指 向 創 建 表 空 間 時 的 物 理 位 置,數 據 存 放 于/home/postgres/tblspc 上。PolarDB 默認有兩個可用的表空間,pg_default 和 pg_glo

25、bal。默認情況下使用pg_default。PolarDB 數據庫結構 29 表數據文件內部被分為多個塊,默認 8k,每個塊都有唯一 ID。上圖右側為數據塊的結構。塊頭里面存放了控制性的信息,比如常見的行指針。存放數據時,順序為從下往上存放,而塊頭的信息為從上往下存放,中間區域即可用空間。一行數據插入到數據塊中,首先,數據會進入塊的底部,塊頭產生指針,指向行開始的位置。插入第二行數據,則會由下往上疊加,并在塊頭產生新的指針。PolarDB 數據庫結構 30 訪問表的方式有兩種:順序掃描:即全表掃描。比如有兩個數據塊,PolarDB 在訪問時會先找到第一個塊的位置,并從第一行開始進行完整掃描;如

26、果沒有,則進入第二個塊的第一行繼續掃描,以此類推。索引掃描:根據索引行里記錄的 rowID 進行掃描,無需全表掃描。啟動 PolarDB 數據庫時,會先啟動實例,實例由進程和內存組成。postgres server process是PolarDB的父進程,所有后臺進程、后端進程等都由父進程派生。backend process 進程負責處理用戶請求,background process 用于管理整個數據庫。PolarDB 數據庫結構 31 Backend process 負責客戶端請求??蛻舳嗽L問數據庫時,并不會直接與數據庫交互,而是將所有請求發給 Backend 進程(相當于代理進程),由它再

27、向 server 進程或后臺進程發出請求。執行結果也由 Backend 進程返回給用戶進程。Prostgers進程通過pg_ctl進行啟動。啟動以后,默認會有一個網絡監聽端口5432,也可以在配置文件中修改監聽端口。如上圖,當前進程名為 postgres,父進程下派生了很多子進程。PolarDB 數據庫結構 32 Backend 進程與用戶進程一一對應,他們之間的連接方式被稱為專用連接。傳統的PG 數據庫只支持專用連接。而 PolarDB 在此基礎之上又開發出與 Oracle 類似的共享連接,后續該能力也將開源,由 max_connections 參數控制數據庫允許的最大連接數。上圖為 Pol

28、arDB 后臺進程的功能。寫進程負責將PolarDB數據緩沖區的臟塊寫到數據文件。檢查點進程用于做檢查點,同時也負責寫。PolarDB 數據庫結構 33 上圖即父進程派生出的子進程。PolarDB 的內存結構分為兩種,分別是本地內存和共享內存。本地內存為每個backend 進程啟動時自動分配,共享內存為整個實例提供服務。PolarDB 數據庫結構 34 本地內存分為以下三種類型:work_mem:執行 SQL 語句時,如果涉及到排序操作、表連接等,則會使用工作內存。maintenance_work_mem:主要用于 vacuum 或者 reindex。temp_buffers:用于存放臨時表。

29、本地內存類似于 Oracle 的 PGA,server 進程相當于 backend,PGA 相當于本地內存。共享內存分為以下幾種類型:shared buffer pool:修改數據文件的數據塊時,會讀到數據緩沖區里進行修改。WAL buffer:進行事務操作時,會分配一個日志緩沖區。commit log:PolarDB 有專門的進程記錄提交的事務信息,因此會分配 commit log 緩沖區,為整個實例提供服務。Foreign Data Wrappers(FDW)使用介紹 35 Foreign Data Wrappers(FDW)使用介紹 FDW(Foreign Data Wrapper)是

30、PolarDB 數據庫提供的與異構數據庫進行數據交流的方式,可以通過 FDW 對異構數據庫進行數據訪問,類似于 Oracle 的 DBLink,但 FDW 的功能更強大。當前,數據庫國產化是一個大趨勢。將數據從 Oracle 遷移到國產數據庫,通過 FDW可輕松實現。但很多開發者在原來的 Oracle 數據庫上使用了包存儲,遷移時涉及到應用、開發上的修改,難度極大,甚至可能還需要開發新的適合國產數據庫的業務。FDW 的訪問與本地訪問一致,不管遠程數據庫是 PG、MySQL 還是 Oracle,通過select count(*)From 即可實現訪問。Foreign Data Wrappers(

31、FDW)使用介紹 36 上圖為 FDW 的執行流程。SQL 語句執行前需要進行解析,訪問 FDW 表也同理,PolarDB 會對 SQL 進行解析。數據表放在另外的數據庫,因此 PolarDB 需要查詢數據字典,確認當前表的創建方式,判斷其是否為外部表。如果是,還需查看外部表所在的服務器以及用戶 mapping。隨后,產生執行計劃,再將要執行的 SQL 語句傳到遠程服務器,最后將結果返回到本地??偨Y來看,FDW 的執行流程分為以下幾步:a)創建查詢樹。b)連到遠程服務器查看是否存在表及其權限。c)本地優化器創建執行計劃。d)根據優化器的執行計劃再還原成文本的 SQL 語句,將 SQL 語句傳到

32、遠程。不同的異構數據庫語法存在差異,此處會轉成異構數據庫能夠兼容的語法。e)遠程服務器執行 SQL 語句,將結果返回給本地。Foreign Data Wrappers(FDW)使用介紹 37 Deparesing 是將執行計劃做反解析,變為 SQL 語句。FDW 從本地將語句傳到遠程,遠程執行完以后再將數據傳回到本地。Foreign Data Wrappers(FDW)使用介紹 38 上圖為遠程服務器上的日志。執行外部的 SQL 語句時,會將事務變為 repeatable read 隔離模式,然后聲明一個游標,綁定游標執行,執行后將數據返回,關閉游標,結束事務。發請求時,遠程服務器有可能被修改

33、,因此我們將事務變為可重復讀的隔離級別。隨著版本的更新,FDW 的功能越來越強大,性能越來越好。FDW 最早在 PG9.3 版本推出。PG9.6 新增了以下特性:如果 SQL 語句帶有排序,則會在遠程排序以后將數據返回到本地,省去本地排序的操作,提高了性能;如果兩張表的連接都為遠程,則會在遠程將兩張表的數據進行連接,連接后將處理結果傳到本地;如果數據庫是 PolarDB對 PolarDB,則可支持 DML 操作;可以根據網絡帶寬的情況設置返回的行數,減少對網絡帶寬的占用。PG10 版本中,新增的特性為:如果操作里帶有聚簇函數的操作,則聚簇的計算在遠程完成,將結果返回到本地,省去了將元數據傳到本

34、地再排序所占據的網絡帶寬。Foreign Data Wrappers(FDW)使用介紹 39 如果兩個數據庫支持 update,比如 PolarDB 對 PolarDB,用 FDW 對遠程的表進行更新時,可以實現不同事務修改同一張表的同一行。而按照以往的情況,該種場景下會造成死鎖。FDW9.5 之前的版本中,多表掃描需要從遠程服務器掃描數據,然后傳到本地,在本地做連接操作。Foreign Data Wrappers(FDW)使用介紹 40 而 FDW9.5 以后,打開 use_remote_estimate,計劃器將通過執行 EXPLAIN 命令向遠程服務器查詢計劃的成本。做多表連接時,連接操

35、作在遠程服務器執行,執行完以后將數據傳到本地,極大減少了數據在網絡之間的傳輸。上圖為 FDW9.5 之前做外部連接的流程,代價較大。上圖為 FDW9.5 后的外部鏈接流程,打開 use_remote_estimate 后,連接在遠程完成,極大提高了查詢性能。Foreign Data Wrappers(FDW)使用介紹 41 在 9.5 版本之前,排序也需要從遠程將數據傳到本地,然后在本地做 sort 操作。而 9.5 之后的版本中,排序操作被下推到遠程服務器,排序完成后將結果返回至本地即可。Foreign Data Wrappers(FDW)使用介紹 42 聚合操作同理。在 10 版本之后,本

36、地不再做聚合,而是由遠程服務器來完成。綜上,新版本的 FDW 性能得到了較大的提高。部署演示 Postgres_FDW 部署 首先,添加擴展,安裝外界PolarDB擴展。創建server并為其命名,傳入遠程PolarDB名、服務端口以及要訪問的數據庫名,用于連接遠程服務器。遠程服務器上應配置好權限,即允許哪臺客戶端訪問服務器。通過des 命令可查看當前有哪些外部服務器以及對應的主機信息,如上圖所示。Foreign Data Wrappers(FDW)使用介紹 43 注意,因為 PolarDB 由很多數據庫組成,在 create FDW 時,在哪個數據庫上部署FDW,則 FDW 只能在該數據庫上

37、使用。創建用戶并為其授權,使其有權創建外部表,然后創建用戶映射。有了用戶映射后,比如遠程服務器是 postgres 用戶,本地的 scott 用戶也可對其進行訪問,即能夠以不同的用戶來訪問不同表的數據。創建外部表,創建時后面需要跟上外部的服務器、schema 以及遠程表的名字。Foreign Data Wrappers(FDW)使用介紹 44 通過d 查詢,當前 scott_pg 用戶下有 dept_fdw 和 emp_fdw 兩個外部表,訪問外部表與訪問本地表沒有任何區別??梢酝ㄟ^ds+emp_fdw 查看該表,結果會顯示它為外部表以及它的訪問模式、遠程服務器等信息。File_FDW 部署

38、Foreign Data Wrappers(FDW)使用介紹 45 首先,添加擴展,創建本地插件,創建基于本地 FDW 的 server,將權限賦予相應的用戶。創建外部表。因為需要引用本地某文本文件里的數據,因此后面需指定 file name 即數據源路徑,并指定格式為 CSV,代表用逗號隔開列與列之間的數據。創建成功后,查看該表。/home/postgres/emp2.csv 文件的產生有兩種方式:其一,如果是外部的文本文件,采集時將列與列之間用逗號隔開即可。其二,如果是自己創建的外部表,通過上圖語句將 emp 的內容進行復制即可。Foreign Data Wrappers(FDW)使用介紹

39、 46 最終,用戶可以像訪問內部表一樣訪問外部表,非常方便。此外,基于文件的外部表為只讀,不能做 DML 操作。用戶和權限管理 47 用戶和權限管理 PG 數據庫下的用戶指用來訪問、管理數據庫中的對象,角色用于管理數據庫訪問權限,簡化權限的管理,同時也兼任用戶功能。用戶和角色的概念非常接近,如果給角色分配了可登錄的權限,角色也可以與用戶一樣登錄并創建對象。因此,在 PG 數據庫下,用戶和角色可以等同看待。用戶和角色在整個數據庫中是全局的,登錄到某數據庫時,創建的用戶不只針對數據庫里的用戶,而是針對整個集群的數據庫。數據庫中的用戶可以分為兩類:超級用戶:安裝完 PolarDB 以后,默認的用戶即

40、超級用戶 postgres,擁有所有權限。普通用戶:根據需要創建。另外,group 指不擁有 replication/noreplication、connection limit 屬性的角色。用戶和權限管理 48 創建用戶有兩種模式:方式一為在操作系統下創建數據庫的用戶,不需要登錄到數據庫。方式二為登錄到數據庫進行創建。方式一的后臺處理時也需要登錄到數據庫進行操作,只是登錄操作由后臺負責,為使用者簡化了流程。如果在數據庫里創建用戶,創建時即可為其分配不同的權限,比如特指定是否為超級管理員、是否有創建數據庫的權限、是否有創建角色的權限、是否有創建用戶的權限、用戶能否繼承所擁有的權限等。此類權限為

41、特殊權限,無法使用 grant 進行授權。用戶和權限管理 49 上圖為創建用戶示例。需要注意,Login、Superuser 和 Createrole 三個權限無法被繼承。創建角色的語法與創建用戶的語法基本一致。角色和用戶最大的區別在于,角色默認沒有 login 的權限,如果有了 login 的權限,則角色等同于用戶。用戶和權限管理 50 上圖為創建角色示例。我們通常用角色對權限進行間接的授權。創建完用戶和角色以后,可以用du 指令顯示用戶和角色的屬性?!敖巧Q”一列下包含了用戶和角色,此處對用戶和角色進行了統一對待,同時展示了屬性以及屬于哪個角色或權限。用戶和權限管理 51 除了du 以外

42、,也可以通過數據字典訪問用戶/角色信息,比如通過 pg_user 或pg_rules。查詢結果顯示為上圖形式。如果要修改用戶的屬性,比如權限、名字或密碼,可以用h alter user 命令。用戶和權限管理 52 上圖為修改用戶屬性示例。修改角色的屬性可以用h alter role 命令。用戶和權限管理 53 上圖為修改角色屬性示例。用戶與角色的刪除有兩種方式。方式一:通過 dropuser 命令刪除用戶。刪除時如果沒有設置信任關系,則需要指定登錄的用戶名、密碼,且此用戶名必須擁有創建用戶的權限,方能登錄到數據庫執行 dropuser 命令。方式二:在 psql 命令行使用 drop 刪除。刪

43、除時需要附上判斷用戶/角色是否存在的語句,避免用戶/角色不存在而產生報錯。尤其是腳本里,如果產生報錯,則會影響后續的執行。注意,只有超級用戶能夠刪除超級用戶,只有具有 createrole 權限的用戶才能刪除非超級用戶。且刪除用戶前,需要刪除依賴該用戶的對象、權限等信息,或將權限授權給其他用戶,以保證對象的安全性。PG 不支持 cascade 此類級聯的刪除方式。此外,當前登錄的對象也無法刪除,需退出登陸后再做刪除操作。用戶和權限管理 54 比如,刪除 u1 時需要先通過d 命令查看其關聯的對象。而除了對象以外,還需要通過dn 查看其是否存在相關 schema。如上圖,顯示 u1 下還存在一個

44、 sport schema,因此,需要通過 drop schema sport 將該 schema 刪除。再次執行刪除 u1 操作,提示在 testdb 上還存在相關權限。需要通過 revoke all 命令將授權給用戶在 testdb 數據庫上的所有權限撤回,隨后即可刪除用戶。為角色授權以后,如果要使用角色里的權限,需要通過 set role 命令啟用該角色。如上圖所示,啟用角色前,不允許創建 schema。而執行 set role 命令后,schema 創建成功。用戶和權限管理 55 每個數據庫對象都有一個 owner,owner 默認情況下擁有該對象的所有權限。數據庫中所有權限都與角色掛

45、鉤。對超級用戶的權限不做檢查,其他用戶需要通過 ACL。對于數據庫對象,所有者和超級用戶可以做任何操作,其他用戶需要通過 ACL。PG 數據庫下的權限管理可以分為幾個層級,分別為實例權限、數據庫權限、表空間、schema 權限以及 object 對象(表、視圖、索引)。用戶和權限管理 56 實例級別的權限主要通過 pg_hba.conf 控制實例訪問的隔離級別來實現。該文件存在于 PGDATA 目錄下,每一列分別為類型、訪問的數據庫、訪問的用戶、客戶端地址以及訪問方式。如上圖,第一條信息中的 host 代表主機,all 代表所有數據庫和用戶,127.0.0.1 指本地地址,trust 指信任,

46、意味本地用戶登陸無需用戶密碼。第二條信息中的 0.0.0.0 指所有外部主機,意為拒絕外部任意主機以 postgres 用戶登錄。第三條信息中的 md5 指通過用戶和密碼登錄。上圖第一行代表任何用戶訪問任何數據庫時都需要密碼訪問。設置完以后通過reload 重新加載方可生效。訪問方式如上圖所示。PolarDB 數據庫上,只要用戶有 login 權限,即允許所有用戶連接到數據庫。另外,不允許除了超級用戶和 owner 以外的任何人在數據庫中創建 schema。系統會自動創建名為 public 的 schema,允許任何人在里面創建對象。用戶和權限管理 57 比如創建一個新的數據庫名為 newdb

47、1,則所有用戶都可以登錄,上圖為以 u2 用戶登錄,而且可以在數據庫上創建表。如上圖,創建了 t1 表,其 schema 屬于 public。因此創建了數據庫以后,默認數據庫下存在 public 模式的 schema,u2 用戶即可以 public 模式創建 t1 表。上圖語句實現了允許用戶在指定的數據庫下做任何操作。用戶和權限管理 58 如上圖,u2用戶想要創建一個schema被拒絕。因為數據庫上已經存在一個schema。而執行 grant create on database newdb1 to u2 語句后,u2 即可在數據庫上創建schema。創建完后,可以看到該數據庫下存在兩個 sc

48、hema 模式,分別是 public和 s1。模式是指某個用戶下所有對象的集合。在 Oracle 下,用戶與模式一一對應。比如“scott 用戶下的 emp 表”嚴謹的表述方式應為“scott 模式下的 emp 對象”。而 PolarDB 下,一個用戶可以有多個模式。比如 scott 用戶下有 sport 和 art 兩個模式,其中 sport 模式下有籃球、羽毛球、乒乓球三張表,art 模式下有鋼琴、小提琴、手風琴三張表。如果不指定模式,則 scott 下的所有表都屬于 public 模式。如果想要沿用與 Oracle 一樣的模式,在用戶下創建一個與用戶名一致的模式即可。用戶和權限管理 59

49、 實現方式如上圖所示,先創建兩個模式。創建表的時候,如果希望將籃球表分至體育模式下,則創建語句寫為 create table sport.lanqiu()。分別在兩個模式下建了不同的表以后,用d 查看會發現無法查詢。因為默認情況下PolarDB 的搜索路徑是與用戶名一致的模式以及 public 模式。因此,需要將 search_path 加上 sport 和 art,方可成功查詢。用戶和權限管理 60 如果要將某個模式下表的數據給某個用戶訪問,首先要先將模式的訪問權限賦予用戶,再將表的訪問權限賦予用戶。如上圖,對 u3 賦予 select 權限后,訪問 art 模式下的 gangqin 表,顯

50、示訪問被拒絕。因為該用戶沒有訪問 art 模式的權限。對 u3 賦予 usage 權限后方可訪問。綜上,如果訪問特殊模式,不是 public 模式,授權時需要分兩步:首先,將模式的權限賦予用戶,其次,將模式下對象的權限賦予用戶。用戶和權限管理 61 數據字典 namespace 里包含了所有模式的名字以及模式下分配給用戶的權限。上圖為為對象級別賦予權限的語法。用戶和權限管理 62 比如要使用 u3 訪問 u2 下的 t1 表,需要執行 grant select on t1 to t3。如果該表不屬于 public 模式,則需要先將模式的訪問權限賦予用戶,再將模式下的對象權限賦予用戶。上圖為對象

51、級別的權限示例。上圖為表的權限含義。用戶和權限管理 63 將權限賦予用戶以后,可以通過 psql 的z 或dp 查看查看當前有哪些可訪問的權限。查詢結果顯示如上圖。比如 u3=r/u2 代表 u3 擁有 r 的權限且屬于 u2。執行 grant all on t1 to u3 將 t1 的所有權限賦予 u3,然后通過z 查詢,結果如上圖,u3=arwdDxt/u2,代表 u3 擁有了所有權限。撤銷權限可通過 REVOKE 語法,示例如上圖。用戶和權限管理 64 比如,執行 revoke all on t1 from u3 后,結果如上圖,原先 t1 賦予 u3 的權限全部被撤銷。VACUUM

52、處理 65 VACUUM 處理 vacuum 的工作內容為空間清理,最主要的工作內容為將數據塊中被刪除的行的空間進行釋放。比如當前的數據塊存在兩行數據,用戶對最下面一行數據做了修改,PolarDB 的操作方式不是在當該行進行修改,而是將該行標識為刪除,然后在數據塊里重新插入修改后的新行。被標識為刪除的行不會立刻釋放空間,而是需要由 vacuum 來做釋放操作。另外,vacuum 還負責冷凍老的 Txid 以及收集表的統計信息,為優化器提供可用信息做參考,并且更新表的文件。VACUUM 處理 66 vacuum 的操作過程分為三部分。第一部分,準備創建死元組列表。需要從各個數據庫里搜索哪些表達到

53、了整理的條件,然后將這些表組成列表。第二部分,清理階段。將列表里包含有被刪除的行的空間進行釋,同時更新 FSM 和VM 兩個文件。第三部分,善后工作。如果最后一頁沒有元組,則將其刪除,以減少數據文件的尺寸。如果需要,同時會將不必要的 Clog 刪除。比如山圖中第一個數據塊內有三行,其中有一行已被刪除,PolarDB 將其標識為dead tuple。做完 vacuum 以后,Tuple_2 的空間被釋放,剩余兩行被整理后更加緊湊。同時,被刪除行的指針沒有刪除,插入新行后,該指針會指向新行,減少了維護操作,提高了效率。VACUUM 處理 67 做 vacuum 時,正常情況下需要將表的所有數據掃描

54、一遍。為了提高效率,PolarDB使用了 VM(可見性地圖)數據文件。如上圖,比如當前有三個數據塊,第二塊里不包含被刪除的行,則 VM 會將其標識為 1。后續做 vacuum 時,會跳過 VM=1 的頁,提高 vacuum 的效率。9.6 版本以后,可見性地圖除了提高 vacuum 的效率以外,同時也提高了凍結的效率。數據庫為了描述事務操作的先后順序,會為事務分配 ID 號,即 TxID。VACUUM 處理 68 TxID 不會無限增大,而是循環使用。最大的可用事務 ID 為 42 億,PolarDB 將其分為兩半,前 21 億代表“過去的或當前正在用的”,此類事務 ID 修改的行為對用戶可見

55、;而后 21 億事務 ID 代表“未來的”,修改的函數不可見。兩個部分的 21 億事務 ID 可以循環使用。比如前面的 21 億使用完以后,再用后面的 21 億,使用完以后再重新使用前面的 21 億。凍結主要針對可見性規則。比如當前正在使用后 21 億的 TxID,而前 21 億中某個數據塊里仍有數據,需要對用戶可見。因此,將其標記為凍結,使得其可見。凍結處理分為懶惰模式和急切模式。懶惰模式指每次小部分、分批次地進行凍結,類似于日常做衛生;急切模式指大批量地凍結,類似于年終大掃除。惰性凍結的公式中,OldestXmin 指當前最小的事務 id,vacuum_freeze_min_age是一個固

56、定參數,默認為 5000 萬。VACUUM 處理 69 以上圖為例,假設當前的最小事務 id 為 50002500,意味著要將小于或等于 2500的 ID 都凍結。凍結時,首先會先判斷 VM 值,如果 VM 為 1(當前數據塊內不存在被刪除的行),則跳過,不對其進行凍結。然后判斷每一個塊內每一行的事務 id,如果 id2500,則跳過。比如上圖中 Turple9 內最后一行 id 為 3000,因此不凍結。急性凍結的觸發條件為:自上一次急性凍結后,TxID 使用了 1 億 5000 萬后會再次觸發。VACUUM 處理 70 如上圖,如果從未做過急性凍結,則 datfrozenxid 默認為 5

57、60。發生急性凍結后,datfrozenxid 會變為該次急性凍結的 TxID。如上圖所示,當前最小的事務 id 為 150002000,150002000-5000000=100002000,因此事務 id 小于 100002000 的行全部進行凍結。比如當前有三個塊,PolarDB 會對三個塊全部進行掃描,事務 ID 小于 100002000的,在該行某一位做 frozen 標記??梢岳斫鉃?,只有很早以前的事務修改的行會被凍結,最新修改的行不凍結。做完凍結后,所有數據庫的列均會寫上被凍結時的 ID,等下一次發生急性凍結時,ID 會被更新。VACUUM 處理 71 查詢結果如上圖,比如 id

58、=651 意味著該表沒有被凍結,此 id 為事務創建時的 id。而 id=0 意味著數據庫是初始化時創建的。為了提高急性凍結的效率,PolarDB 在 VM 上又做了改進。上次凍結后(包括惰性凍結與急性凍結)至今沒有發生變化的,狀態為 1;上次惰性凍結沒有發生的,狀態為 0;凍結后發生變化的,狀態為 0。做急性凍結時,狀態為 1 則跳過,狀態為 0 則進行急性凍結,以減少凍結工作量。VACUUM 處理 72 PolarDB9.6 以后,提供了專門的后臺進程做 autovacuum。默認每 10 分鐘執行一次,由 autovacuum 參數定義間隔時間。每次做 vacuum 時,默認用三個 wo

59、rker 進程,每個進程同一時間只能負責一個數據 庫 里 的 表。如 果 想 增 加autovacuum的 進 程 數,可 以 通 過autovacuum_max_workers 參數進行修改。vacuum 分為普通 vacuum 和 Full Vacuum。上圖為普通 vacuum 操作。比如當前有三個塊,紫色標示都是被刪除的行。做了普通 vacuum 以后,三個塊均保留,但里面只有少量數據。VACUUM 處理 73 為了減少數據文件的尺寸,可以做 Full Vacuum。將塊中被刪除的行的空間清理后,會再新建一個數據文件,為其分配一個塊。然后將剩下的行放入新的數據文件的塊中,將原來的數據文

60、件刪除。如果檢測到數據塊很多,且每個塊內的可用空間也很多時,建議做 Full Vacuum。比如上圖,表中一共有 1640 個數據塊,每個數據塊內的可用空間為 99 個字節。對該表做 delete 操作并進行普通 vacuum 后,每個塊的可用空間為 7124 字節,空閑率達 86.97%。VACUUM 處理 74 而對該表做 Full Vacuum 后,表內只剩 164 個數據塊,且每個塊內的可用空間為 0,數據文件的尺寸大幅降低。如上圖所示,表內原先有 94 個塊,做完普通 vacuum 后依然為 94 個塊,但是做了Full Vacuum 后,只剩 10 個塊。將來做全表掃描時,掃描量從

61、 94 個塊降低至 10 個塊,掃描效率得到了極大提升。緩沖區管理器 75 緩沖區管理器 緩沖區管理器位于用戶和數據庫存儲之間,用戶進程請求數據塊時,由緩沖區管理器從數據庫存儲層將數據塊讀取到數據緩沖區提供服務。數據緩沖區內存放的是數據塊,包含表和索引的塊、可用性地圖的塊、可見性地圖的塊以及緩沖區索引塊。緩沖區管理器分為三層,第一層為緩沖區表層,第二層為緩沖區描述層,第三層為緩沖區池層(負責將數據塊從數據文件讀到內存)。緩沖區描述層包含大量信息,也是對于管理最重要的一層。緩沖區管理器 76 緩沖區表層存在很多插槽,每個插槽里存放了數據塊的標記,標記里包含了對于要訪問的數據塊的描述,比如哪個數據

62、文件的第幾個塊。每個槽里記錄了一個或多個標記。比如緩沖區標記為(16821、16384、37721)、0、7,其中 16821、16384、37721分別代表對象 oid、數據庫 oid 以及表空間 oid,0 代表頁面的 fork number,7 代表頁面 number。緩沖區管理器 77 將數據塊讀到數據緩沖區需要記錄信息,此類信息存放在描述層。描述層里包含了緩沖區的 tag 信息以及 buffer_id。PolarDB 將緩沖區分為多個大小相同的塊,每個塊都有自己的 buffer_id。refcount 和 usage_count 用于描述緩沖區被訪問的熱度。緩沖區被某個進程訪問過一次

63、,refcount 和 usage_count 均會+1。與此同時,如果緩沖區被時鐘掃描過后refcount-1,refcount=0 代表該緩沖區可用。Flag 有三個狀態,其中 dirty bit 代表緩沖區已經被修改過;valid bit 代表已經被寫到數據文件,當前可用;io_in_progress bit 代表正在被進程處理。緩沖池層是連接描述層與表層非常重要的一層,它將內存分割為若干個內存塊,每個內存塊都有一個 buffer_id。緩沖區管理器 78 將數據塊讀取到數據緩沖區的流程如下:首先,發送一個請求,請求到達描述層后分配一個插槽,管理器將數據塊的標記記錄在描述里,同時從數據緩

64、沖區層申請內存塊,將緩沖數據塊的標記從數據庫讀到緩沖區,并發送 Buffer_id,使得塊的標記與 Buffer_id 的標記能夠進行匹配。假如數據塊是 8k,則緩沖池會被分割為若干個 8k 的池槽,正好等于數據塊的大小。Backend 訪問數據塊時,讀取數據的流程如下:首先,將進程要訪問的數據塊標記發送給管理器,并由管理器負責尋找當前哪個 ID存在可用空間。然后管理器將找到的 Buffer_id 發送給用戶進程并記錄到描述層,緩沖區管理器 79 管理器的后臺將數據塊讀到數據緩沖區。后臺進程得到 Buffer_id 以后,根據Buffer_id 找到數據塊。如果下一次要讀同樣的塊,backen

65、d 進程會將需要訪問的 buffer tag 發送給管理器,管理器掃描該數據塊是否曾被訪問過。如果有,則查詢該數據塊當前放在哪個Buffer_id 并將 Buffer_id 發給 backend 進程,然后進行訪問。由于數據塊已經存在緩沖區,因此不再需要從磁盤里讀數據塊。數據緩沖區的大小固定,無法將整個數據庫的數據都存放在內存中,因此數據緩沖區的空間應輪流重復使用,需要做替換。通常,頁面替換的算法有兩種,分別為 LRU 即最近最少使用規則(Oracle 使用的算法)以及時鐘掃描。時鐘掃描:描述層里通過 refcount 參數記錄了數據塊曾經被訪問過的次數,進程訪問一次則+1,被時鐘掃描過一次則

66、-1,以此判斷數據塊當前的受歡迎程度。如果refcount 為 0 則代表該數據塊可用。如上圖,圖里時鐘指向的數據塊 refcount=3,則跳過,繼續指向下一個數據塊。圖里指向的 refcount=2,對其做-1 操作,繼續指向下一個數據塊。圖里指向的 refcount=0,代表該塊可用,因此可分配給進程使用。緩沖區管理器 80 LRU 算法和時鐘掃描算法的本質都是根據數據塊當前被關注的程度來判斷其是否可被替換。數據緩沖區里的數據塊被修改以后,會被標識為臟塊。PolarDB 提供了 checkpointer和 background writer 兩個進程用于寫臟塊。Oracle 也提供了兩個

67、進程,但是只由 DBWriter 負責寫臟塊,檢查點進程只負責向數據緩沖區發信號。檢查點進程會將檢查點的記錄寫到 WAL 日志文件,再將相應的臟塊寫到數據文件。寫操作屬于密集型操作,會影響數據庫的性能,因此,此處寫的機制為一點一點地刷新臟頁,以求對數據庫活動的影響最低。默認情況下,每次寫 100 個數據塊,200 毫秒寫入一次??衫斫鉃榫彌_區不斷地被修改,又不斷地保存。過了一段時間再發檢查點時,會將上一次發生檢查點到目前為止的所有臟塊都寫入。緩沖區管理器 81 可以通過 shared_buffers 參數來控制共享緩沖區的尺寸,共享緩沖區內包含數據緩沖區里的內容??梢酝ㄟ^ wal_buffer

68、s 控制日志緩沖區的尺寸。effectiv_cache_size默認為 4G,用于告知優化器內核中可用的緩存量,為掃描方式的選擇提供參考性意見。備份與恢復 82 備份與恢復 PolarDB 是基于共享存儲的存算分離架構,因此 PolarDB 的備份恢復和 PostgreSQL存在部分差異。本文將指導您如何對 PolarDB 做備份恢復,搭建只讀節點,搭建Standby 實例等:PolarDB 備份恢復原理 PolarDB 的目錄結構 polar_basebackup 備份工具 PolarDB 搭建 RO PolarDB 搭建 Standby PolarDB 按時間點恢復 備份恢復原理 Pola

69、rDB 的備份恢復原理整體上和 PostgreSQL 幾乎一致,總結為以下幾步:執行 pg_start_backup 命令 使用各種方式對數據庫進行復制 執行 pg_stop_backup 命令 進行備份的更簡單方法是使用 polar_basebackup,但它其實是在內部發出這些低級命令,并且支持使用網絡將文件發送到遠端。備份與恢復 83 pg_start_backup:準備進行基本備份?;謴瓦^程從 REDO 點開始,因此pg_start_backup必須執行檢查點以在開始進行基本備份時顯式創建REDO點。此外,其檢查點的檢查點位置必須保存在 pg_control 以外的文件中,因為在備份期

70、間可能會多次執行常規檢查點。因此 pg_start_backup 執行以下四個操作:?強制進入整頁寫模式。?切換到當前的 WAL 段文件。?做檢查點。?創建一個 backup_label 文件該文件在基礎目錄的頂層創建,包含關于基礎備份本身的基本信息,例如該檢查點的檢查點位置。第三和第四個操作是這個命令的核心;執行第一和第二操作以更可靠地恢復數據庫集群。pg_stop_backup:執行以下五個操作來完成備份。?如果已被pg_start_backup強制更改,則重置為非整頁寫入模式。?寫一條備份端的 XLOG 記錄。?切換 WAL 段文件。?創 建 備 份 歷 史 文 件 該 文 件 包 含b

71、ackup_label文 件 的 內 容 和pg_stop_backup已執行的時間戳。?刪除backup_label文件從基本備份恢復需要backup_label文件,一旦復制,在原始數據庫集群中就不需要了。目錄結構 如上所述,PolarDB 備份過程總體可以概括為三步,其中第二步是使用各種方式對數據庫進行復制:手動 copy 使用網絡工具傳輸 基于存儲進行打快照。因此,這里介紹一下 PolarDB 數據目錄結構,以便于進一步理解備份恢復。備份與恢復 84 如上圖,PolarDB 是基于共享存儲的,所以 PolarDB 在物理上有兩個重要的數據目錄,分別是本地存儲目錄和共享存儲目錄。本地存儲

72、目錄 1.postgres=#show data_directory;2.data_directory 3.-4./home/postgres/primary 5.(1 row)可以通過上述命令在數據庫中獲取本地存儲目錄的位置,可以看到它是類似于PostgreSQL 的數據目錄。1.2.base 3.1 4.13938 5.13939 6.13940 7.global 8.pg_commit_ts 9.pg_csnlog 10.pg_dynshmem 11.pg_log 12.pg_logical 13.mappings 14.snapshots 15.pg_logindex 備份與恢復 85

73、 16.pg_multixact 17.members 18.offsets 19.pg_notify 20.pg_replslot 21.pg_serial 22.pg_snapshots 23.pg_stat 24.pg_stat_tmp 25.pg_subtrans 26.pg_tblspc 27.pg_xact 28.polar_cache_trash 29.polar_fullpage 30.polar_rel_size_cache 本地存儲目錄中,大多都是通過 initdb 命令生成的文件或目錄。隨著數據庫服務運行,這里會生成更多的本地文件,如臨時文件、緩存文件、配置文件、日志文件

74、。由于本地存儲目錄中的文件不涉及核心數據,因此在做備份時本地存儲目錄是可選的。您可以僅備份共享存儲上的數據目錄,然后用 initdb 重新生成一份新的本地存儲目錄。但是需要記住之前的本地配置信息,如 postgresql.conf,pg_hba.conf 等。提示 如果您不能記住歷史配置,或者您需要保留歷史日志,建議您將本地存儲目錄也進行備份??梢詫⑦@個目錄完全復制后修改配置文件來搭建 RO 或者 Standby。共享存儲目錄 1.postgres=#show polar_datadir;2.polar_datadir 3.-4./nvme0n1/shared_data/5.(1 row)備份

75、與恢復 86 1.2.3.base 4.1 5.16555 6.16556 7.16557 8.16558 9.global 10.pg_commit_ts 11.pg_csnlog 12.pg_logindex 13.pg_multixact 14.members 15.offsets 16.pg_replslot 17.pg_tblspc 18.pg_twophase 19.pg_wal 20.archive_status 21.pg_xact 22.polar_dma 23.consensus_cc_log 24.consensus_log 25.polar_flog 26.polar_

76、flog_index 27.polar_fraindex 28.fbpoint 29.pg_xact 30.polar_fullpage 共享存儲目錄中存放 PolarDB 的核心數據文件,如表文件、索引文件、WAL 日志、DMA、LogIndex、Flashback 等。這些文件被一個 RW 節點和多個 RO 節點共享,因此是必須備份的。您可以使用 copy 命令、存儲快照、網絡傳輸等方式進行備份。如果您沒有更好的選擇,推薦使用 polar_basebackup 命令。polar_basebackup 備份工具 下面介紹一下 PolarDB 的備份工具 polar_basebackup,它由

77、 pg_basebackup 備份與恢復 87 改造而來,且完全兼容 pg_baseabckup,也就是說它同樣可以用于對 PostgreSQL做備份恢復。polar_basebackup 在 PolarDB 二進制安裝目錄下的 bin/目錄中,您可以配置 export 環境變量來直接使用它。1.2.polar_basebackup takes a base backup of a running PostgreSQL server.3.4.Usage:5.polar_basebackup OPTION.6.7.Options controlling the output:8.-D,-pgda

78、ta=DIRECTORY receive base backup into directory 9.-F,-format=p|t output format(plain(default),tar)10.-r,-max-rate=RATE maximum transfer rate to transfer data directory 11.(in kB/s,or use suffix k or M)12.-R,-write-recovery-conf 13.write recovery.conf for replication 14.-T,-tablespace-mapping=OLDDIR=

79、NEWDIR 15.relocate tablespace in OLDDIR to NEWDIR 16.-waldir=WALDIR location for the write-ahead log directory 17.-X,-wal-method=none|fetch|stream 18.include required WAL files with specified method 19.-z,-gzip compress tar output 20.-Z,-compress=0-9 compress tar output with given compression level

80、21.22.General options:23.-c,-checkpoint=fast|spread 24.set fast or spread checkpointing 25.-C,-create-slot create replication slot 26.-l,-label=LABEL set backup label 27.-n,-no-clean do not clean up after errors 28.-N,-no-sync do not wait for changes to be written safely to disk 29.-P,-progress show

81、 progress information 30.-S,-slot=SLOTNAME replication slot to use 31.-v,-verbose output verbose messages 32.-V,-version output version information,then exit 33.-no-slot prevent creation of temporary replication slot 34.-no-verify-checksums 35.do not verify checksums 備份與恢復 88 36.-?,-help show this h

82、elp,then exit 37.38.Connection options:39.-d,-dbname=CONNSTR connection string 40.-h,-host=HOSTNAME database server host or socket directory 41.-p,-port=PORT database server port number 42.-s,-status-interval=INTERVAL 43.time between status packets sent to server(in seconds)44.-U,-username=NAME conn

83、ect as specified database user 45.-w,-no-password never prompt for password 46.-W,-password force password prompt(should happen automatically)47.-polardata=datadir receive polar data backup into directory 48.-polar_disk_home=disk_home polar_disk_home for polar data backup 49.-polar_host_id=host_id p

84、olar_host_id for polar data backup 50.-polar_storage_cluster_name=cluster_name polar_storage_cluster_name for polar data backup 可以看到 polar_basebackup 的大部分參數及用法都和 pg_basebackup 一致,只是多了以下幾個參數,下面重點來介紹一下:polardata:如果您備份的實例是 PolarDB 共享存儲架構,這個參數用于指定PolarDB 共 享 存 儲 目 錄 的 位 置。如 果 您 不 指 定,將 會 使 用 默 認 目 錄pola

85、r_shared_data,并且放在本地存儲目錄(即-D/-pgdata 所指定的參數)下面。如果您對 PostgreSQL 備份則無需關心他。polar_disk_home:如果您備份的實例是 PolarDB 共享存儲架構,且您希望將共享存儲目錄通過 PFS 寫入共享存儲設備,則需要指定這個參數,它是 PFS 的使用參數。polar_host_id:如果您備份的實例是 PolarDB 共享存儲架構,且您希望將共享存儲目錄通過 PFS 寫入共享存儲設備,則需要指定這個參數,它是 PFS 的使用參數。備份與恢復 89 polar_storage_cluster_name:如果您備份的實例是 Po

86、larDB 共享存儲架構,且您希望將共享存儲目錄通過 PFS 寫入共享存儲設備,則需要指定這個參數,它是 PFS 的使用參數。搭建 RO 您可以通過以下兩種方式來搭建 RO node。使用 initdb 來搭建 RO 主要步驟是使用 initdb 初始化 RO 的本地存儲目錄,然后修改配置文件,啟動實例。具體請參考只讀節點部署。備份 RW 的本地存儲目錄來搭建 RO 這里使用備份 RW 的本地存儲目錄。下面通過 polar_basebakcup 來演示:1.polar_basebackup-host=主節點所在 IP-port=5432-D/home/postgres/replica1-X s

87、tream-progress-write-recovery-conf-v 完成 polar_basebackup 命令后,我們可以看到/home/postgres/replica1 中存在一個 polar_shared_data,搭建 RO 時不需要它,將它刪除:1.rm-rf/home/postgres/replica1/polar_shared_data 打開/home/postgres/replica1/postgresql.conf,修改如下配置項:備份與恢復 90 1.2.port=5433 3.polar_hostid=2 4.polar_enable_shared_storage

88、_mode=on 5.polar_disk_name=nvme0n1 6.polar_datadir=/nvme0n1/shared_data/7.polar_vfs.localfs_mode=off 8.shared_preload_libraries=$libdir/polar_vfs,$libdir/polar_worker 9.polar_storage_cluster_name=disk 10.logging_collector=on 11.log_line_prefix=%pt%rt%ut%mt 12.log_directory=pg_log 13.listen_addresses

89、=*14.max_connections=1000 15.synchronous_standby_names=打開/home/postgres/replica1/recovery.conf,使用以下配置項替換文件中的所有內容:1.polar_replica=on 2.recovery_target_timeline=latest 3.primary_slot_name=replica1 4.primary_conninfo=host=主節點所在IP port=5432 user=postgres dbname=postgres application_name=replica1 最后,啟動只讀

90、節點:1.$HOME/tmp_basedir_polardb_pg_1100_bld/bin/pg_ctl start-D$HOME/replica1 檢查只讀節點能否正常運行:1.$HOME/tmp_basedir_polardb_pg_1100_bld/bin/psql 2.-p 5433 備份與恢復 91 3.-d postgres 4.-c select version();5.version 6.-7.PostgreSQL 11.9(POLARDB 11.9)8.(1 row)搭建 Standby 您可以使用全量備份集搭建 Standby,這里推薦使用 polar_basebacku

91、p 進行搭建,下面介紹搭建流程。使用 polar_basebakcup 對實例作全量備份 1.polar_basebackup-host=主節點所在 IP-port=5432-D/home/postgres/standby-polardata=/nvme0n2/shared_data/-polar_storage_cluster_name=disk-polar_disk_name=nvme0n2 -polar_host_id=3-X stream-progress-write-recovery-conf-v 提示 注意:這里是構建共享存儲的 Standby,首先您需要找一臺機器部署好 Pola

92、rDB 及其文件系統 PolarFS,且已經搭建好了共享存儲 nvme0n2,具體操作請參考準備塊設備與搭建文件系統。備份完成后如下圖所示:備份與恢復 92 提示 如果您沒有共享存儲設備,則不需要指定-polar_storage_cluster_name,-polar_disk_name,-polar_host_id 參數。下面我們簡單介紹下其他形態的 PolarDB 備份:1.-單節點本地備份 2.polar_basebackup-D/polardb/data-standby-X stream -progress-write-recovery-conf-v 3.-共享存儲本地備份 4.pol

93、ar_basebackup-D/polardb/data-standby-polardata=/polardb/data-local -X stream-progress-write-recovery-conf-v 5.-共享存儲寫入 pfs 6.polar_basebackup-D/polardb/data-standby-polardata=/nvme7n1/data -polar_storage_cluster_name=disk-polar_disk_name=nvme7n1 -polar_host_id=3 檢查備份是否正常 查看本地目錄:查看共享存儲目錄:備份與恢復 93 修改 p

94、ostgresql.conf 將參數修改為如下所示:1.polar_hostid=3 2.polar_disk_name=nvme0n2 3.polar_datadir=/nvme0n2/shared_data 4.polar_storage_cluster_name=disk 5.synchronous_standby_names=在主庫中創建復制槽 1.psql-host=主節點所在 IP -port=5432-d postgres-c SELECT*FROM pg_create_physical_replication_slot(standby1);2.slot_name|lsn 3.-

95、+-4.standby1|5.(1 row)修改 Standby 本地目錄配置 在 Standby 的本地存儲目錄中 recovery.conf 文件中增加如下參數:1.recovery_target_timeline=latest 2.primary_slot_name=standby1 啟動 Standby 1.$HOME/tmp_basedir_polardb_pg_1100_bld/bin/pg_ctl start-D$HOME/standby 備份與恢復 94 驗證 Standby 1.psql-host=master 所在 IP-port=5432-d postgres-c cre

96、ate table t(t1 int primary key,t2 int);insert into t values(1,1),(2,3),(3,3);2.CREATE TABLE 3.INSERT 0 3 1.psql-host=standby 所在 IP-port=5432-d postgres-c select*from t;2.t1|t2 3.-+-4.1|1 5.2|3 6.3|3 7.(3 rows)按時間點恢復 可以參考 PostgreSQL 按時間點恢復 PITR。其原理如圖所示,使用備份集加上歸檔日志,可以恢復出任意歷史時刻的 PolarDB 實例:共享存儲原理與實踐 95

97、 共享存儲原理與實踐 一、整體介紹 傳統 RDS 架構在高可用的實現上采用了主備復制的模式,通過 Binlog 邏輯復制保證高可用。該架構存在以下幾個問題:增加計算節點需要同步擴容存儲,導致存儲成本隨著節點增加而上升。擴展只讀節點較麻煩,需要進行數據重建。在數據量較大的情況下,數據重建耗時較久,可能會影響 HA 的耗時。不同于傳統的主備復制,PolarDB 采用共享存儲架構,存儲和計算分離,中間通過PolarFS 分布式的文件系統和存儲進行共享數據。共享存儲原理與實踐 96 RW 負責數據寫入,主要流程為:RW 調用文件系統的 API,文件系統經過內部處理將數據寫入到共享存儲,數據的可靠性依賴

98、于共享存儲的多副本機制。因此在 DB 層面,無需關心多份數據的寫入。因為天然存在多副本的機制,對于 DB 而言,只需寫一份數據在共享存儲。共享存儲中,所有節點可共享同一份數據,PolarFS 分布式文件系統天然解決了一寫多讀場景下的數據一致性問題。該架構下存儲和計算節點分離,計算節點的擴容和存儲節點的擴容互相不耦合,均可單獨進行擴容。并且因為共享一份數據,新增RO 節點時,無需再進行數據重建,可以秒級拉起 RO 節點,存儲層面也可獨立擴容,無需擴容計算節點。PolarFS 文件系統是專門為 DB 設計的用戶態文件系統,并且基于共享存儲支持了一寫多讀的實現,向上提供兼容 posix 的接口。寫節

99、點的數據寫入流程如下:調用 PolarFS 創建目錄,PolarFS 將數據寫入到共享存儲。由于采用了共享存儲的機制,數據已經存在于存儲內,但是因為 PolarFS 層面本身也有文件系統的元數據,需要在 RO 節點上通過日志同步的方式進行感知。以上設計的好處在于 PolarFS 提供 posix 兼容,DB 無需再大刀闊斧地改造代碼,可以以較小的代價實現分布式架構,并且天然地在共享存儲架構下實現了高可用。比如新增 RO 或 HA 的場景下,相較主備復制,它無需進行數據拷貝,RTO 可達到分鐘級甚至秒級。共享存儲原理與實踐 97 PolarFS 和常見的文件系統類似,主要有以下幾個元數據的概念。

100、Direntry:記錄文件或目錄的名字。Inode:描述文件或目錄的基本屬性,比如 inode 類型、文件長度、atime/mtime/ctime 等。Blktag:描述該 block 所屬的文件以及在文件中的位置,每個 block 都擁有一個對應的 blktag。比如上圖,創建 gcc 文件并進行寫入時,需要為其分配數據塊空間,每個數據塊默認大小為 4M,需要分配大于 4M 的空間時,將多個 block 進行連接,達到索引鏈接的目的。文件系統的目錄輸入采用了典型的樹狀結構。共享存儲原理與實踐 98 文件系統中需要進行 MakeFS 的操作,目的為對文件系統的空間進行劃分,將底層的共享存儲塊設

101、備進行管理。假設是 40G 的存儲設備,PolarFS 將按照實際的 chunk 對空間進行劃分,劃分出 4個 chunk 的空間。每個 chunk 內部又劃分了大小為 4M 的多個 block。每個 chunk的第0個block將作為superblock,用于記錄文件系統的元數據信息,多為blktag、direntry 以及 inode。每一個 4 兆的 superblock 最多可以存儲 2048 個 direntry 和inode,意味著每個 chunk 下可以創建 2048 個文件或目錄。除了 superblock 之外的所有的 datablock 用于存放文件的數據,共有 2560

102、個。blktag 元數據會負責管理 datablock,映射到 datablock。使用 PolarFS 文件系統時,首先會執行格式化,主要目的是將元數據在 superblock內進行格式。日志是文件系統中很重要的組成。文件系統對文件的修改往往涉及多個不同類型的元數據修改,如果修改不能原子性完成,則會造成數據的不一致或損壞。PolarFS 的日志除了保證事務提交的完整性,還有一個關鍵用途為通過一寫多讀同步數據。共享存儲原理與實踐 99 文件系統內部有很多元數據需要進行管理,當 RW 節點對內部的元數據進行修改之后,如果要保證一致性,RO 節點上也需要對元數據進行同樣的修改,才能保證一致性。該能

103、力通過 Journal 的設計實現。Journal 文件是固定大小的空間,其中 head lsn 為當前事務提交到的最新位點。因為日志是循環覆蓋寫的過程,如果日志提交后空間不夠,需要做 checkpoint 操作,將日志 trim 到磁盤上,變更也將反映到磁盤的共享存儲上。checkpoint 操作可將位點不停地推進,將塊空間進行釋放,用于提交新的 log。RW 提交元數據之后,RO 要訪問文件時,首先會讀取最新位點。同時,RO 內部本身會維護已有的事務位點,然后判斷最新位點與已有事務位點的差距,比如最新位點為 10,已有位點為 5,則意味著中間有 5 個事務尚未同步。RO 會將這 5 個數據

104、進行同步,并進行內存回放。同步完以后,將 RO 本身的已有事務位點更新至 10。二、PolarFS 共享存儲系統的搭建 首先,從 github 下載源代碼,進行編譯、安裝代碼。源碼地址 https:/ 共享存儲原理與實踐 100 文檔地址 https:/ 安裝后,系統即存在 PFS 對應的工具。執行 PFS 命令可查看 PFS 支持的命令行。使用文件系統的第一步是對文件系統進行格式化,需要 sudo 的權限,因為需要進行磁盤的格式化。命令中的-C disk 指的是針對塊設備,因為 PolarFS 支持不同的存儲形態,除了塊設備之外,也支持阿里內部自研的分布式共享存儲 PolarStore。mk

105、fs 命令下的提供了多種選項,比如指定的 logsize 大小,number users 用于控制并發的實例編號。如果對以上選項不了解,采用默認值即可。共享存儲原理與實踐 101 通過上述語句進行格式化。如果文件系統之前曾被格式化,本次格式化則需要加上-f,意為強制格式化。對于單節點,塊設備直接只用本地磁盤即可。PFS 除了支持共享存儲,也支持單機硬盤,但是單機硬盤無法實現跨節點的數據訪問。日常開發可以使用單機模式進行格式。格式化成功之后,通過 ls 命令查看文件系統下的文件??梢酝ㄟ^ mkdir 命令創建目錄,執行后沒有報錯則意味著創建成功。通過 ls 命令查看,結果顯示 nvme6n1 文

106、件下已經存在 testDir 目錄。PolarDB 使用多個進程進行數據通信。主進程進行新的請求時,會 fork 一個 work子進程,每個進程下面都會引入 PolarFS 的客戶端,包含了 read、write 等常見操作,并負責調用客戶端的接口,與后臺的 pfsdaemon 進程進行通訊。共享存儲原理與實踐 102 用戶態共享內存作為 PolarFS 的通信信道,最大的優點在于可以減少數據的拷貝。比如客戶端要寫 buffer,將數據存入共享內存,PID 文件系統可以直接將數據取出,間接實現了零拷貝的操作。上圖為此前默認安裝的 pfsdaemon。通過 start_pfsd.sh-p 命令即

107、可調用。-p 指定文件系統的盤符。Fuse 類似于文件系統訪問的中間層,對上兼容標準的文件系統的語義操作,對下可對接不同的文件系統。通過標準的命令,可直接訪問到底層的 PolarFS。比如此前查看 PolarFS 的目錄需要通過 PFS 工具,但是接入 fuse 之后,直接使用fuse Linux 的原生命令 makeDir 即可創建目錄到 PFS。共享存儲原理與實踐 103 首先安裝 Fuse,具體安裝步驟可參考 github 上的安裝文檔。安裝完成后,將 fuse掛載到 PFS 上,系統默認提供了現成的腳本進行掛在操作(如上圖所示),腳本在安裝時已經部署在機器上。腳本下需要提供三個參數,d

108、iskname 指定塊設備的名稱;RW 和 RO 參數代表啟動讀寫實例和只讀實例的意思,因為需要創建文件和創建目錄等寫操作,此處啟動讀寫實例;mount_dir 指 fuse 的掛載目錄。掛載成功后,可進入 fuse 目錄訪問。執行 ll 操作,結果可直接顯示 PFS 的 testDir??芍苯油ㄟ^原生的 Linux 的命令創建 dir 和文件。共享存儲原理與實踐 104 可以看到創建的目錄和文件都已經同步到 PFS 的文件系統,說明通過 fuse 成功訪問了 PFS 文件系統。Fuse 最大的作用為簡化文件系統的操作,用原生命令即可達到訪問 PFS 文件系統的目的。用完之后,可通過 moun

109、t_dir 接觸 Fuse 掛載。PolarFS 文件系統支持不同的掛載形態和存儲介質,其中 PolarStore 是阿里云數據庫內部自研的分布式共享文件系統,通過 RDMA 在存儲層進行數據的多副本機制的通信以及復制。當前,阿里云官網在售的 PolarDB 產品均基于 PolarStore 形態實現,支持 PolarDB-MySQL 的 5.6、5.7、8.0 版本,PolarDB-PostgreSQL11 以及 PolarDB-Oracle 兼容版本。共享存儲原理與實踐 105 阿里云的 ESSD 是標準的分布式塊設備共享存儲,可在阿里云上直接購買。部署方式與單機較類似,區別為 ESSD

110、在底層是分布式的共享存儲,通過 ESSD 也可以達到一寫多讀進行數據共享以及數據同步一致性的效果。Ceph 是業界流行的分布式存儲系統,對上層暴露了多種存儲接口,比如 RDB 為塊存儲的接口,可以模擬出一個塊設備供用戶使用,RadosGW 是對象存儲的接口,下面可以對接 S3 等,CephFS 是 Ceph 對外暴露的文件系統接口。PolarFS 本身已經是一個文件系統,因此此處主要使用的為 RBD 的形態。共享存儲原理與實踐 106 首先,安裝 Ceph 端。模擬單機節點搭建單機的 Ceph 集群,在一臺機器上指定的三個存儲盤,分別是 7n1、8n1、9n1。Ceph 環境已提前搭建好,可以

111、看到 7n1、8n1、9n1 已經映射到 Ceph 的集群中,由 OSD 進程管理。通過 ceph osd pool create rbd_pool 8 8 創建 rbd 的存儲池,通過 rdb create rbd_pool/volume01 將存儲池映射到卷,然后通過 rbd map rbd_pool/volume01 將卷映射為塊設備。上圖中 rbd 0 即通過 Ceph 映射出的塊設備,可以對塊設備進行操作,操作方式與單機的硬盤操作一致。共享存儲原理與實踐 107 上圖為對塊設備執行 mkfs 操作后的結果展示。上圖為創建目錄操作。另外,還可通過 Ceph 的塊設備進行 PolarFS

112、 文件的讀寫。云原生 HTAP 108 云原生 HTAP PolarDB-PG 是云原生數據庫,具有存儲計算分離的架構??梢愿鶕脩粜枰獜椥詳U充存儲節點,也可以根據用戶的計算需求彈性擴充用戶的計算節點。但是如果使用原生的 PolarDB-PG 處理 HTAP 場景,在處理 AP 場景時會遇到兩個挑戰。第一,單機的 PG 只支持單機的串行與單機的并行,不支持多機查詢和跨機查詢,無法發揮多個計算節點的特性,CPU 和 memory 無法橫向的 scale out,只能單機scale up,即必須增加 CPU 和 memory 的實例規格。第二,原生的 PG 直接套用到 PolarDB 上,無法充分

113、發揮共享存儲池的大吞吐能力,因為只能利用單機計算節點上的 RO 能力。而根據 TP 和 AP 在存儲和計算上是否共享與分離的維度,可以分為三種:第一,TP 和 AP 在存儲計算上都分離,即分為 TP 與 AP 兩套獨立的系統。TP 的數據需要導入到 AP 系統中,存在延遲、時效性不高的問題。同時兩份存儲也增加了冗余、存儲成本以及運維難度。第二,TP 和 AP 在存儲和計算上都共享。該模式對 TP 和 AP 查詢時或多或少都會造成一些影響。同時,受限于 TP 查詢,AP 比重增大時,無法彈性 scale out,同樣也只能在單機上調整自己的 CPU 與 memory。云原生 HTAP 109 第

114、三,TP 和 AP 在存儲上共享,在計算上分離,即 PolarDB 云原生 HTAP 的方案。PolarDB 云原生 HTAP 的整體架構如上圖所示。底層為共享存儲池,上層為多個計算節點,每個計算節點內包含了一個讀寫節點和多個 RO 節點。由于 TP 和 AP 共享一套存儲,減少了存儲成本,可以提高查詢的時效性,能提供秒毫秒級的數據新鮮度。其次,TP 查詢受限于 RO 節點與 RW 節點,而 AP 查詢僅受限于部分 RO 節點,因此可以實現 TP 與 AP 的物理隔離,并杜絕了 CPU 與 memory 的相互影響。另外,該架構具備 Serverless 的彈性擴展能力,可以在任何 RO 級聯

115、上發起分布式MPP 查詢,可以彈性調整 MPP 執行節點的范圍,可以彈性調整單機 MPP 的單機并行度。最后,該架構消除了數據的存儲傾斜和計算傾斜,在執行過程中也可充分考慮到 PG Buffer Pool 的親和性。由于 PolarDB 底層存儲在不同節點上是共享的,因此不能像傳統 MPP 一樣掃表。我們在原先的單機執行引擎上支持了 MPP 分布式執行引擎(跨機執行引擎)。同時對 Shared-Storage 做了優化,基于 Shared-Storage 的 MPP 是業界首創。其基本原理為借助 Shuffle 算子屏蔽數據的分布,借助 ParallelScan 算子屏蔽共享存儲。云原生 HT

116、AP 110 上圖是典型的火山模型,掃描 A 表,再掃描 B 表進行 HashJoin,最后做聚合輸出。而 PolarDB 的 MPP 場景下,對 A 表和 B 表進行了虛擬分區。兩個只讀節點上默配置了一個 worker。左側只讀節點上的 worker 會掃描 A 表的 Virtual Partition-1,右側節點上的 worker 會掃描 A 表的 Virtual Partition-2。B 表同理。通過對 Virtual Partition-1 和 Virtual Partition-2 虛擬表的共同掃描,屏蔽了共享存儲。通過 Shuffle 算子的分發之后,分發到上層進行 HashJ

117、oin 的時,已經屏蔽了數據的分布。而上述執行計劃必然需要有優化器的支持。我們基于社區的 ORCA 優化器擴展了能感知共享存儲特性的 Transformation Rules。使得能夠探索共享存儲下特有的 Plan空間,比如:一張表在 PolarDB 中既可以全量掃描,也可以分區域掃描,這是與傳統 MPP 的本質區別。上圖中的 A 表按照分片掃描,但是如果 B 是小表,則可以做全表掃描。每個子節點都會掃描 B 的全量數據,構建一張哈希表。掃描 B 表的數據不需要下發到各個節點上。云原生 HTAP 111 上圖灰色部分是 PolarDB 內核 PORCA 優化器的適配部分。下半部分是 ORCA

118、內核,灰色模塊是我們在 ORCA 內核中對共享存儲特性所做的擴展。PolarDB 中有 4 類算子需要并行化,其中 Seqscan 的算子的并行化極具代表性。為了最大限度地利用存儲的大 IO 帶寬,在順序掃描時,按照 4MB 為單位做邏輯切分,盡量將 IO 打散到不同的盤上,達到所有盤同時提供讀服務的效果。該方案還有一個優勢在于每個只讀節點只掃描部分表文件,最終能緩存的表大小是所有只讀節點的 BufferPool 總和。云原生 HTAP 112 上圖可見,通過增加只讀節點,掃描性能線性提升 30 倍。打開 buffer 后,掃描時間從 37min 降至 3.75s,提升了 600 倍。這也是數

119、據親和性的優勢所在。傾斜是傳統 MPP 固有的問題,主要包含兩方面:一方面是存儲的傾斜,大對象通過heap 內部表關聯 toast 表時,因為無法確切地知道實際存儲的數據量有多大,無論怎么切分,數據存儲都有可能不均衡;另一方面是執行時的傾斜。不同只讀節點上的事務、buffer、網絡等會抖動,因此也會存在執行計算傾斜。云原生 HTAP 113 為了解決傾斜問題,我們支持了動態掃描。將協調節點內部分成 DataThread 和ControlThread,其中 DataThread 負責收集匯總元組,ControlThread 負責控制每個掃描算子的掃描進度。每個算子控制每個節點上 scan 算子的

120、掃描進度,每個節點上 scan 算子再掃描下一個塊的數據時會向 QC 節點進行請求查詢,從而獲得下一個掃描的目標塊,使得掃描快的工作進程能多掃描邏輯的數據切片。此外,盡管是冬天分配,過程中我們也盡量考慮了 buffer 數據親和性。另外,每個算子的上下文均存儲在各個 worker 的私有內存中,協調節點不存儲表的相關信息。上圖可見,出現大對象時,靜態掃描會出現數據傾斜,而使用動態掃描并沒有因為 RO 節點增多導致數據傾斜嚴重。我們利用數據共享的特點,還可支持云原生下極致彈性的要求:將 Coordinator 全鏈路上各個模塊所需要的外部依賴存在共享存儲上,每個節點都可以看到相同的數據。同時 w

121、orker 全鏈路需要的運行時參數通過控制鏈路從 Coordinator 同步,使Coordinator 和 worker 無狀態化。任何節點都可以作為協調節點,確定了協調節點之后,控制節點再從協調節點獲取相關的控制信息。以上方式帶來的好處在于:SQL 的任何只讀節點都可以稱為協調節點,解決了協調節點單點的問題。其次,SQL 可以在任何節點上起任意數量的 worker,使算力達到SQL 級別的彈性擴展,使得業務有更多的調度策略。云原生 HTAP 114 比如四個只讀節點,可以讓業務域 1 的 SQL 只利用只讀節點 1 和只讀節點 2,業務域 2 的 SQL 利用節點 3 和節點 4,為用戶提

122、供更多選擇。多個計算節點通過等待回放和 globalsnapshot 機制完成。等待回放能夠保證所有需要的數據版本已經同步完成,globalsnapshot 能夠保證選取統一的可讀版本。主要流程如下:用戶 SQL 發送后,生成計劃并確定協調節點,協調節點會廣播ReadLSN,每個 worker 節點等待回放到 ReadLSN。結束之后獲取各自的 snapshot,通過序列化發送給協調節點。協調節點匯總所有 worker,選出最小的 snapshot 并通過廣播發給各個節點,再由廣播執行計劃樹,從而可以保證每個 worker 能看到相同的數據、相同的快照和相同的 plan,最終開始執行。上圖為使

123、用 1TB 的 TPCH 進行的測試。云原生 HTAP 115 Demo 演示:利用 PolarDB HTAP 加速 TPC-H 首先,更新鏡像,啟動 Docker。確認實例已經拉起,進行連接。生成 TPC-H 測試數據集,使用 tpch-dbgen 工具生成任意大小的數據集。云原生 HTAP 116 導入建表語句。導入數據。對表的最大并行度進行限制。默認情況下,不支持對 PX 查詢的表設置最大并行度,PX 即分布式執行引擎。開啟每張表的最大 worker 數,大于 1 則表示可以支持 MPP 查詢。云原生 HTAP 117 執行單機的單機并行的執行引擎。并行度設置為 2,上圖為使用單機并行執

124、行 tpch查詢 q18 的計劃。執行 q18.sql,結果顯示花費 12 秒。接下來執行 PolarDB 的 MPP 執行引擎。云原生 HTAP 118 打開 px 開關,將單機并行設置為 1,查看執行計劃。查看執行效果,耗時 5s。云原生 HTAP 119 將并度設置為 2,查看執行計劃,如上圖。計劃中顯示,有 4 個 worker 在工作,數據匯總到一個節點上。查看執行效果,執行時間為 3s,與并行度為 1 時相比,有了將近一倍的提升。最佳場景實踐與壓測 120 最佳場景實踐與壓測 TPC 是一個專門負責制定計算機事務處理能力測試標準并監督其執行的第三方組織,其中被業界廣泛使用的測試方式

125、有四種,分別是有 TPC-C、TPC-E、TPC-H 和 TPC-DS。前兩者針對 OLTP 業務,后兩者針對 OLAP 業務。OLTP 主要執行日常的事務處理,包括大量增刪改查,其特點為高并發、高性能,且滿足 ACID 特性。而 OLAP 主要用于數據倉庫,支持非常復雜的查詢,查詢結果側重于決策支持,其特點為對實時性要求不高,數據量大。最佳場景實踐與壓測 121 TPC-E 與 TPC-C 的主要差別在于難度,TPC-E 可以理解為是 TPC-C 的升級版,測試內容更復雜,要求更高。TPC-C 的業務模型為批發零售業務,主要業務為訂單的處理能力,涉及 5 種事務、9 張表以及 4 大常見的數

126、據類型。TPC-E 模擬的是證券交易系統,實時性要求更高。它模擬了 10 種實時事務、2 種批處理事務。TPC-C 模擬的是一個在線零售公司的業務場景,假設倉庫里包含 10 萬個產品,負責十個區域的供貨,每個區域都有單獨的訂單系統,一個區域管理 300 個客戶,因此倉庫總共涉及到 3 萬個客戶。樹狀圖如上。最佳場景實踐與壓測 122 上圖為 TPC-C 涉及到的 9 張表。其中 New-Order 表示未發貨的訂單,發貨后即刪除,初始值為每個倉庫 9000 條;Order 為總訂單表,每新增一個客戶訂單會增加一條記錄,不會刪除,初始化為每個客戶一條訂單,初始值為倉庫數*每個倉庫的商品數量。TP

127、C-C 業務數據模型 TPC-C 測試的能力為每分鐘處理完成的事務數,主要針對 neworders 表。事務數越大,說明處理能力越高。最佳場景實踐與壓測 123 TPC-C 在部署時,數據倉庫的數量也會影響業務的復雜程度。另外,TPC-C 也可用于測試同樣的硬件配置、同樣的業務量下,Oracle 和 PolarDB 的處理性能。TPC-C 測試完后,可以將字符的報告格式化成 HTML 形式,使其更具可讀性。TPC-H 主要針對數倉,提供了兩種測試方式,其中 TPC-H 較為簡單,TPC-DS 較為復雜,支持子表達式、關聯子查詢、聚簇、排序等數據分析時的常用語法。最佳場景實踐與壓測 124 OL

128、AP 是 TPC-H 的測試標準,主要針統計分析、數據挖掘、分析處理等。TPC-H 模擬了一個數據庫模型,容量可以在 1-10000 GB 幾個級別種進行選擇,其中包含了八張表,提供了 22 個決策系統里常用的查詢語句,比如分組、排序、聚集、子查詢、關聯等。比如一條查詢語句用于查詢表的定價報告,該語句的特點是帶有分組、排序、聚集操作并存的單表查詢。查詢會訪問表中 95%-97%的行。因此可見,SQL 語句會根據業務量、復雜度以及涉及到的數據量來判斷處理能力。最佳場景實踐與壓測 125 比如某語句用于查詢最小代價供貨商,則該語句為設計排序、聚集、子查詢的多表查詢??梢越Y合 JeMeter 工具將

129、 TPC-H 測試出的結果以圖形的方式予以展示,方便后續在報表內使用。另外,PolarDB 也支持 pgbench。TPC-C、TPC-H 的部署需要專門的軟件,相對較為復雜。而 pgbench 是系統自帶的測試系統,可以測試并發的量。其優點為系統自帶,短小精悍,容易擴展。如果期望功能更強大,可以在網站下載免費插件。缺點為測試結果浮動較大,需要多做幾次測試然后取平均值。此外,執行過程中無法終端測試操作,只能等測試結束。最佳場景實踐與壓測 126 pgbench 測試的指標為 TBS 每秒鐘處理的事務量。PolarDB-PG基于PostgreSQL開發,因此能夠支持所有PostgreSQL原生態的插件。

友情提示

1、下載報告失敗解決辦法
2、PDF文件下載后,可能會被瀏覽器默認打開,此種情況可以點擊瀏覽器菜單,保存網頁到桌面,就可以正常下載了。
3、本站不支持迅雷下載,請使用電腦自帶的IE瀏覽器,或者360瀏覽器、谷歌瀏覽器下載即可。
4、本站報告下載后的文檔和圖紙-無水印,預覽文檔經過壓縮,下載后原文更清晰。

本文(阿里云:PolarDB for PostgreSQL 開源必讀手冊(125頁).pdf)為本站 (好好學習) 主動上傳,三個皮匠報告文庫僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對上載內容本身不做任何修改或編輯。 若此文所含內容侵犯了您的版權或隱私,請立即通知三個皮匠報告文庫(點擊聯系客服),我們立即給予刪除!

溫馨提示:如果因為網速或其他原因下載失敗請重新下載,重復下載不扣分。
客服
商務合作
小程序
服務號
折疊
午夜网日韩中文字幕,日韩Av中文字幕久久,亚洲中文字幕在线一区二区,最新中文字幕在线视频网站