PostgreSQL 11 新特性之跨分割槽移動資料
阿新 • • 發佈:2019-01-11
文章目錄
在 PostgreSQL 10 中,如果 UPDATE 語句修改了分割槽欄位的值,導致資料需要移動到其他分割槽時,語句將會失敗。
-- PostgreSQL 10
CREATE TABLE rtable(c1 INT, c2 VARCHAR(10)) PARTITION BY RANGE(c1);
CREATE TABLE rtable100 PARTITION OF rtable FOR VALUES FROM (1) TO (100);
CREATE TABLE rtable200 PARTITION OF rtable FOR VALUES FROM (101 ) TO (200);
INSERT INTO rtable(c1, c2) VALUES (50, 'val50');
SELECT * FROM rtable100;
c1 | c2
----+-------
50 | val50
(1 row)
以下語句更新分割槽欄位 c1,導致記錄(c1 = 50)需要移動到分割槽 rtable200;不過語句執行失敗。
-- PostgreSQL 10
UPDATE rtable
postgres-# SET c1 = c1 + 100
postgres-# WHERE c1 = 50;
ERROR: new row for relation "rtable100" violates partition constraint
DETAIL: Failing row contains (150, val50).
PostgreSQL 11 能夠正確處理更新分割槽欄位的操作:
-- PostgreSQL 11
CREATE TABLE rtable(c1 INT, c2 VARCHAR(10)) PARTITION BY RANGE(c1);
CREATE TABLE rtable100 PARTITION OF rtable FOR VALUES FROM (1) TO (100);
CREATE TABLE rtable200 PARTITION OF rtable FOR VALUES FROM (101) TO (200);
INSERT INTO rtable(c1, c2) VALUES (50, 'val50');
SELECT * FROM rtable100;
c1 | c2
----+-------
50 | val50
(1 row)
UPDATE rtable
SET c1 = c1 + 100
WHERE c1 = 50;
SELECT * FROM rtable200;
c1 | c2
-----+-------
150 | val50
(1 row)
根據提交記錄,這種 UPDATE 語句實際上分為兩步執行:從舊的分割槽中 DELETE 相應記錄,在新的分割槽中INSERT 相應記錄。對於併發場景,這種方式可能會產生意料之外的行為。官方已經記錄該問題,並且等待提交補丁。
另外,跨分割槽移動資料的 UPDATE 語句將會導致觸發器的執行順序更加複雜,相關資訊可以參考“PostgreSQL 11 新特性之分割槽錶行級觸發器”。
官方文件:Table Partitioning
人生本來短暫,你又何必匆匆!點個贊再走吧!