定義
PG雖然是C語言,但是其代碼實現包含很多面向對象的思想,主要包含:
- 繼承:通過將一個結構體(作為基類)放到另一個結構體(作為子類)的第一個字段,從而實現繼承。
- 方法:通過在結構體中定義函數指針類型的字段,從而實現屬性和方法的綁定
- 接口類:將一系列函數指針封裝為一個結構體,該結構體只有方法沒有屬性,就是接口類(類似C++純虛類)
方案分析
經過前期分析,我們基于社區PG14版本,整理出社區關于TableAM的特性修改集中在26個提交,涉及文件修改286處,新增代碼10012行,刪除代碼5939行。主要涉及的改動如下:
- 對一些核心的數據結構進行了抽象和優化:將其調整為與具體存儲引擎無關的基類,并將原有關于
Heap表的對應結構修改為這些基類的子類,主要包括:- TupleTableSlot:在內存中存放tuple的容器類。該結構體在TeleDBX中已經存在,TableAM對其進行重新定義,包括:
- 將一些通用的字段保留在結構體中,將TupleTableSlot變成1個基類
- 在TupleTableSlot上派生出BufferHeapTupleTableSlot、HeapTupleTableSlot、MinimalTupleTableSlot和VirtualTupleTableSlot四種子類,分別對應4種tuple的管理方式
- 對TupleTableSlot相關的一系列函數抽象為TupleTableSlotOps接口類,作為屬性綁定到TupleTableSlot類
- 對heap表的一系列slot相關操作進行二次封裝,將其定義為4個全局的接口對象,對應4種TupleTableSlot子類
- TableScanDesc:描述順序掃描的類。該結構體是新增的,改動包括:
- 抽象了
TableScanDesc類型用于描述順序掃描 - 將
HeapScanDesc中一些字段放入TableScanDesc,然后將HeapScanDesc實現為其子類
- 抽象了
- ParallelTableScanDesc & ParallelBlockTableScanWorker:描述并行掃描的類,該結構體為新增,改動包括:
- 將
ParallelHeapScanDesc拆分抽象為ParallelTableScanDesc和ParallelBlockTableScanWorker
- 將
- IndexFetchTableData:描述索引掃描的類,該結構體是新增的,改動包括:
- 在
IndexScanDescData對象中增加了IndexFetchTableData類型的屬性xs_heapfetch - 基于
IndexFetchTableData對象在TableAmRoutine中封裝了一系列索引掃描的方法
- 在
- TupleTableSlot:在內存中存放tuple的容器類。該結構體在TeleDBX中已經存在,TableAM對其進行重新定義,包括:
- 引入了TableAmRoutine這個接口類作為自定義存儲引擎的接口,其包含了一系列接口,主要包括:
- 對應TupleTableSlot對象的TupleTableSlotOps接口類
- 順序掃描方法
- 并行掃描方法
- 索引掃描方法
- 元組讀相關方法
- 元組寫相關方法
- DDL相關方法
- Planner相關方法
- Executor相關方法
- 其它方法
- 將現有heap表作為一種存儲引擎,適配到TableAM
- 將一些核心的類封裝為TableAM類的子類
- 將一些核心的方法封裝為TableAM類的方法
- 將執行器中與存儲引擎的對接代碼從heap接口轉換為TableAM虛函數
- 元數據修改
- pg_type新增類型:table_am_handler
- pg_proc新增函數:heap_tableam_handler、table_am_handler_in、table_am_handler_out
- pg_class一些系統表的relam字段值變更為PGHEAPAM
- 語法及功能
- 擴展
CREATE ACCESS METHOD語法,在IndexAM基礎上支持TableAM CREATE TABLE增加table_access_method_clause,指定TableAM
- 擴展
- 其它修改
- 要通過ObjectAddress建立Reletion和其AccessMethod對象的依賴關系
- 新增了
default_table_access_method參數指定默認的TableAccessMethod - 修改
\d表結構的描述信息,增加TableAccessMethod相關描述信息(可選)
除了上訴修改,在合入過程中還有幾個需要考慮的點:
- PG14相對TeleDB for Xscale的基線版本PG10有很多新增特性
- TeleDB for Xscale作為分布式數據庫,和PG也會有大量不同的地方
而TableAM作為從代碼層面進行的優化,涉及大量接口的新增、刪除和調整,必然會存在不兼容的地方,導致無法直接合入社區patch,只能在理解patch的基礎上將其適配到TeleDB for Xscale內核,過程中要基于如下原則:
- 結構體要保持完全兼容,必要情況下可以增加字段
- 方法的參數保持完全兼容,必要情況下可以增加參數
具體到執行階段,有兩種策略:
- 基于社區commit,逐個合入并進行測試驗證
- 直接基于社區最新代碼,通過對比進行整體合入,最后整體測試驗證
最后綜合考慮工作量和可執行路徑,我們選擇了后者,理由如下:
- 社區很多commit也處于中間狀態,會有方案來回調整的情況,挨個commit合入等于重復這些方案調整的過程,工作量巨大
- 由于TeleDB for Xscale相對于社區PG,在內核層面已經進行了大量修改,很多commit都需要進行人工修改適配,而帶個commit進行這種適配無疑會進一步增加工作量
總結
目前TeleDB for Xscale已經完成了TableAM框架的引入工作,并在此基礎上引入了原地更新引擎和列存引擎等多個存儲引擎。