問題描述
在使用pg_partman外掛程式對RDS PostgreSQL資料庫進行分區表管理時,通過介面create_parent為一張父表建立分區,可能會遇到以下錯誤:
ERROR: duplicate key value violates unique constraint "part_config_parent_table_pkey"問題原因
pg_partman使用表part_config來管理表分區的資訊。然而,該表僅在使用外掛程式介面時維護相關分區資訊。如果之前建立了同名分區表,並且採用DROP TABLE直接刪除了該表,則part_config表中的相關資訊不會被清理。再次建立同名的分區表時,將會出現錯誤:ERROR: duplicate key value violates unique constraint "part_config_parent_table_pkey"。
複現方法
-- 建立分區表
CREATE TABLE part_test(a INT PRIMARY KEY,b INT) PARTITION BY RANGE (a);
SELECT create_parent(p_parent_table=>'public.part_test',p_control=>'a',p_interval=>'10',p_premake=>10);
DROP TABLE part_test;
-- 建立同名分區表
CREATE TABLE part_test(a INT PRIMARY KEY,b INT) PARTITION BY RANGE (a);
SELECT create_parent(p_parent_table=>'public.part_test',p_control=>'a',p_interval=>'10',p_premake=>10);解決方案
pg_partman提供了介面undo_partition用於解除父表的分區,在刪除表前,需要先執行這個函數,對中繼資料進行清理。例如,刪除part_test表前,可以使用如下SQL,清理中繼資料。
-- 建立一張相同結構的非分區表
CREATE TABLE part_test_bak(a INT PRIMARY KEY,b INT);
-- 撤消分區,將分區表的資料移轉到非分區表裡
SELECT undo_partition('public.part_test',p_target_table := 'public.part_test_bak');
-- 刪除原父表
DROP TABLE part_test;在使用外掛程式的情境下,直接使用DROP TABLE命令刪除父表並不是最佳實務。為了確保在刪除表時相關的中繼資料得到及時更新,可以考慮利用事件觸發程序(EVENT TRIGGER)。通過這一機制,可以在執行DDL操作時,自動處理和更新中繼資料表,從而維護資料的一致性和完整性。
更多相關討論,請參見pg_partman社區。