文章目录
在 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, '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
人生本来短暂,你又何必匆匆!点个赞再走吧!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。