RDS PostgreSQL的rds_online_migrate外掛程式提供了線上資料分割函數,可以將普通錶轉換為分區表。
背景
隨著業務發展,資料量會逐漸增多,在特定情境下,可能需要將普通錶轉換為分區表,但是原生PostgreSQL資料庫並沒有提供將普通錶轉換為分區表的線上資料分割函數。為了簡化營運操作,降低分區行為對業務的影響,RDS PostgreSQL提供了線上資料分割函數。
適用範圍
RDS PostgreSQL執行個體版本需要滿足以下條件:
執行個體大版本:13或以上版本。
核心小版本:大於等於20251130。
注意事項
在執行線上分區操作前,請詳細閱讀並確認以下事項,以確保資料安全和操作成功。
前置準備
備份與測試:執行任何操作前,務必確認已有有效全量備份組,並在非生產環境中完成充分的演練與驗證。
儲存空間規劃:線上分區過程中,系統會建立一張新表用於資料移轉。因此,需要預留至少為原表及其所有索引總大小兩倍以上的儲存空間。
資料庫參數配置:此功能依賴邏輯解碼(Logical Decoding)實現,需將
wal_level參數設定為logical。此外,若需並存執行多個分區任務,可能需要相應調高max_worker_processes參數的值。
表結構與許可權要求
主鍵或唯一標識:由於功能內部基於PostgreSQL的原生邏輯複製,源表必須擁有主鍵(
PRIMARY KEY)或已設定REPLICA IDENTITY。使用者權限:執行操作的使用者帳號必須具備以下許可權:建立
publication、subscription和replication slot的許可權,以及對源表和目標表執行RENAME操作的許可權。許可權一致性:為確保商務持續性,遷移前請授予業務帳號對目標資料分割表的相應操作許可權,確保其許可權與源表一致。
異常處理與風險
非原子性操作:此功能為指令碼化流程,不具備原子性。若執行過程中發生異常中斷,可能導致內部對象殘留。
手動清理:發生異常中斷後,可能需要手動清理報錯日誌中殘留的
rds_online_migrate.internal_map表記錄、publication、subscription及replication slot對象。請參考以下命令進行清理:-- 清理中繼資料記錄 DELETE FROM rds_online_migrate.internal_map WHERE src_relname = 'source_table' AND dst_relname = 'destination_table'; -- 刪除殘留的發布 DROP PUBLICATION publication_name; -- 刪除殘留的訂閱 DROP SUBSCRIPTION subscription_name; -- 刪除殘留的複製槽 SELECT pg_drop_replication_slot('slot_name');
RENAME 操作的潛在影響
關聯對象重建:
RENAME操作完成後,依賴於原表的視圖(View)、觸發器(Trigger)和外鍵約束需要手動重建。邏輯複製影響:若源表已加入其他邏輯複製任務,
RENAME操作可能會中斷該複製鏈路。操作完成後,需將新表(原目標表)重新添加到相應的publication中。
功能適用情境擴充
該功能同樣支援對已有分區表進行線上重分區。
使用樣本
以下樣本將示範如何將一個名為 public.test 的普通表線上轉換為分區表。
1. 設定資料庫參數
rds_online_migrate功能依賴邏輯解碼(Logical Decoding)。在RDS控制台中將wal_level參數設定為logical。
2. 準備源表和資料
建立一個普通表public.test作為轉換的源表,並插入一百萬行測試資料,以類比業務真實情境。
-- 建立源表
CREATE TABLE public.test(id int4 PRIMARY KEY, info text);
-- 插入類比資料
INSERT INTO public.test SELECT x, repeat(x::text, 2) FROM generate_series(1, 1000000) AS x;3. 安裝外掛程式
在需要執行操作的資料庫中建立rds_online_migrate外掛程式。
CREATE EXTENSION rds_online_migrate;4. 建立目標資料分割表
建立一個與源表結構相同的目標資料分割表public.test_p。該表必須與源表位於同一Schema下。本樣本建立一個按ID雜湊分割的表,包含四個子分區。
CREATE TABLE public.test_p (LIKE test INCLUDING ALL) PARTITION BY HASH(id);
CREATE TABLE public.test_p_0 PARTITION OF public.test_p FOR VALUES WITH (MODULUS 4, REMAINDER 0);
CREATE TABLE public.test_p_1 PARTITION OF public.test_p FOR VALUES WITH (MODULUS 4, REMAINDER 1);
CREATE TABLE public.test_p_2 PARTITION OF public.test_p FOR VALUES WITH (MODULUS 4, REMAINDER 2);
CREATE TABLE public.test_p_3 PARTITION OF public.test_p FOR VALUES WITH (MODULUS 4, REMAINDER 3);5. 執行線上轉換
調用rds_online_migrate.rewrite_table函數啟動線上分區流程。函數的第一個參數是源表名稱,第二個參數是目標資料分割表名稱。函數返回t表示執行成功。
SELECT rds_online_migrate.rewrite_table('public.test', 'public.test_p');
-- 預期輸出:
rewrite_table
---------------
t
(1 row)6. 驗證轉換結果
操作成功後,函數會自動完成表名切換,以保證業務的無縫過渡:
原表
public.test被重新命名為public.test_rds_bkp,作為資料備份,供後續驗證,可自行刪除。目標資料分割表
public.test_p被重新命名為public.test,作為新表使用。
接下來,通過以下步驟進行驗證:
檢查表結構 使用
\d命令查看關係列表,確認表名已按預期切換,並且新的test表類型為partitioned table。testdb=> \d -- 預期輸出: List of relations Schema | Name | Type | Owner --------+--------------+-------------------+----------- public | test | partitioned table | rds_super public | test_p_0 | table | rds_super public | test_p_1 | table | rds_super public | test_p_2 | table | rds_super public | test_p_3 | table | rds_super public | test_rds_bkp | table | rds_super (6 rows)驗證資料完整性 分別查詢新表、備份表和各分區的資料行數,確保資料移轉完整且分布正確。
查詢備份表總行數,應與遷移前一致。
SELECT count(*) FROM public.test_rds_bkp; -- 預期輸出:1000000查詢新分區表總行數,應與備份表一致。
SELECT count(*) FROM public.test; -- 預期輸出:1000000查詢各分區行數,驗證資料已按雜湊規則分布到各子表。
SELECT count(*) FROM public.test_p_0; -- 預期輸出:249589 SELECT count(*) FROM public.test_p_1; -- 預期輸出:250376 SELECT count(*) FROM public.test_p_2; -- 預期輸出:249786 SELECT count(*) FROM public.test_p_3; -- 預期輸出:250249