GaussDB(DWS)运维 -- 常见问题分析 -- 更新/删除报错

举报
譡里个檔 发表于 2021/04/25 15:53:47 2021/04/25
1w+ 1 1
【摘要】 并发更新报错处理方案

【报错信息】

并发更新(UPDATE/DELETE/MERGE)同一个表的时候,有时候会触发以下两种报错

ERROR:  concurrent update under Stream mode is not yet supported

-- 这种报错信息主要出现在更新目标表是行存表的场景。这种场景可以通过下面章节的描述进行规避

ERROR:These rows have been deleted or updated

-- 这种报错信息主要出现在更新目标表是列存表的场景。这种报错尽量从业务层面规避,如果业务层面不能规避,那么只能把目标修改为行存表,然后按照第一种报错信息同样的方法进行规避

【触发原因】

1) 数据更新(update/delete)时,发现满足更新条件的记录已经被别的事物T1更新,但是事物T1尚未提交

2) 执行数据更新(update/delete)的语句走了stream计划,且数据更新算子下层含有stream算子[见附1]

预             置           条           件
CREATE TABLE t1(a int, b int) DISTRIBUTE BY HASH(a);
CREATE TABLE t2(a int, b int) DISTRIBUTE BY HASH(a);

INSERT INTO t1 VALUES(1, 1);
INSERT INTO t2 VALUES(1, 1);
UPDATE  场  景  触  发  条  件
时间线 SESSION 1.0 SESSION 2.0
1 START TRANSACTION; START TRANSACTION;
2 UPDATE t1 SET b = 2;  
3   UPDATE t1 SET b = 2 FROM (SELECT * FROM t2 WHERE b = 1)t WHERE t.b = t1.a;
4 COMMIT;  
5   执行报错
ERROR:  concurrent update under Stream mode is not yet supported
DELETE  场  景  触  发  条  件
时间线 SESSION 1.0 SESSION 2.0
1 START TRANSACTION; START TRANSACTION;
2 UPDATE t1 SET b = 2;  
3   DELETE FROM t1 USING (SELECT * FROM t2 WHERE b = 1)t WHERE t.b = t1.a;
4 COMMIT;  
5   执行报错
ERROR:  concurrent update under Stream mode is not yet supported

【解决方法】

消除数据更新(update/delete)算子下面的stream算子,可以通过以下两个步骤解决

1. 把要关联的结果集写到临时表中

实际业务场景中更新的关联结果集可能比较复杂,为了可以完美的消除stream算子,可以将关联结果集转储到一个临时表中,比如本文示例中的“SELECT * FROM t2 WHERE b = 1”这个查询就是要更新的关联结果集

1.1) 如果更新(update/delete)的目标表的分布列出现在更新关联列上,临时表的分布列设置为关联条件列,且分布列的数据类型跟对端一致

1.2) 如果更新(update/delete)的目标表的分布列没有出现在更新关联列上,临时表定义为复制表

比如当前示例中的两个SQL,数据更新(update/delete)的关联条件是 t.b = t1.a, 因此可以把关联结果集转储的中间表的分布列定义为b;

CREATE TEMP TABLE t DISTRIBUTE BY HASH(b) AS SELECT * FROM t2 WHERE b = 1;

 临时表t尽量使用hash表,因为复制表实际写数据量比较大,可能会引入性能问题

2. 使用临时表跟更新(update/delete)的目标表做联动更新

   如本文示例,关联结果集转储之后,更新语句可以改写为如下SQL

UPDATE t1 SET b = 2 FROM t WHERE t.b = t1.a;
DELETE FROM t1 USING t WHERE t.b = t1.a;

附1) 

示例中的UPDATE计划,可以看到UPDATE下层存在算子Streaming(type: REDISTRIBUTE)

示例中的DELETE计划,可以看到DELETE下层存在算子Streaming(type: REDISTRIBUTE)

图标--大尾标.png

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(1

抱歉,系统识别当前为高风险访问,暂不支持该操作
  • 作者头像

    你是猴子请来的救兵吗2024/08/27 02:33:311楼举报回复

    merge场景无法消除steam算子,需要改为upsert语法
    MERGE INTO t1 o
        USING t2 t ON (o.a = t.a )
        WHEN MATCHED THEN
        UPDATE SET o.b = t.b WHEN NOT MATCHED THEN
        INSERT (a, b) VALUES (t.a, t.b);
    改为
    INSERT into t1 select * from t2 ON CONFLICT(a) DO UPDATE SET b = EXCLUDED.b;

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。