【PostgreSQL里insert on conflict do操作时的冲突报错分析】

news2024/11/23 18:51:42

最近在巡检PostgreSQL的数据库的时候,发现部分数据库里存在大量的如下报错

ERROR:  ON CONFLICT DO UPDATE command cannot affect row a second time
HINT:  Ensure that no rows proposed for insertion within the same command have duplicate constrained values.

image.png

一、问题分析

通过报错的字段可以看出是使用了PostgreSQL 9.5 引入的一项新功能,insert on conflict do功能,即UPSERT的效果,当插入遇到约束错误时,直接返回,或者改为执行UPDATE。观察日志可以看出执行的SQL是带有多条记录的,推测多条记录的key值冲突了,因此报了这个错。

PostgreSQL 的 upsert 功能:当记录不存在时,执行插入;否则,进行更新。

PostgreSQL的代码里src/backend/executor/nodeModifyTable.c下的ExecOnConflictUpdate()函数里的注释部分其实解释的很清楚了。当在同一命令中再次更新刚插入的元组时,可能会发生这种情况。例如,因为插入了多个具有相同冲突键值的行。

MERGE 也有同样的问题,SQL-2003标准也类似地规定MERGE,在尝试更新同一行两次时必须引发异常。因为一次请求中对行的处理,顺序是不固定的,数据库不知道应该以哪条为最后需要保留的数据。

注释部分也明确表示出现这种问题属于用户的责任,PostgreSQL不会主动去处理这种报错,这种不在同一条SQL中出现多条相同KEY的数据的问题应该让用户去保障。

image.png

二、问题复现

1.建立测试表


postgres<16.1>(ConnAs[postgres]:PID[1103345] 2024-04-16/14:09:21)=# create table test(id int primary key, info text, crt_time timestamp);
CREATE TABLE
postgres<16.1>(ConnAs[postgres]:PID[1103345] 2024-04-16/14:09:22)=#  insert into test values (1,'test',now()) on conflict (id) do update set info=excluded.info,crt_time=excluded.crt_time;
INSERT 0 1
postgres<16.1>(ConnAs[postgres]:PID[1103345] 2024-04-16/14:09:44)=# select * from test;
+----+------+----------------------------+
| id | info |          crt_time          |
+----+------+----------------------------+
|  1 | test | 2024-04-16 14:09:44.405528 |
+----+------+----------------------------+
(1 row)

postgres<16.1>(ConnAs[postgres]:PID[1103345] 2024-04-16/14:09:51)=#  insert into test values (2,'hah','2024-04-16 14:01:33.640731') on conflict (id) do update set info=excluded.info,crt_time=excluded.crt_time;
INSERT 0 1
postgres<16.1>(ConnAs[postgres]:PID[1103345] 2024-04-16/14:10:01)=# select * from test;
+----+------+----------------------------+
| id | info |          crt_time          |
+----+------+----------------------------+
|  1 | test | 2024-04-16 14:09:44.405528 |
|  2 | hah  | 2024-04-16 14:01:33.640731 |
+----+------+----------------------------+
(2 rows)

image.png

2.模拟连续两次插入同样的主键值

可以看到,id是主键,我连续两次插入id=7,但是没有主键冲突,原本的insert变成了更新,把id=7的其他字段进行了更新。

postgres<16.1>(ConnAs[postgres]:PID[1103345] 2024-04-16/14:11:22)=#  insert into test values (7,'test',now()) on conflict (id) do update set info=excluded.
info,crt_time=excluded.crt_time;
INSERT 0 1
postgres<16.1>(ConnAs[postgres]:PID[1103345] 2024-04-16/14:11:38)=# select * from test where id=7;
+----+------+----------------------------+
| id | info |          crt_time          |
+----+------+----------------------------+
|  7 | test | 2024-04-16 14:11:38.229476 |
+----+------+----------------------------+
(1 row)

postgres<16.1>(ConnAs[postgres]:PID[1103345] 2024-04-16/14:11:51)=#  insert into test values (7,'ha','2024-04-16 14:15:38.229476') on conflict (id) do upda
te set info=excluded.info,crt_time=excluded.crt_time;
INSERT 0 1
postgres<16.1>(ConnAs[postgres]:PID[1103345] 2024-04-16/14:12:11)=# select * from test where id=7;
+----+------+----------------------------+
| id | info |          crt_time          |
+----+------+----------------------------+
|  7 | ha   | 2024-04-16 14:15:38.229476 |
+----+------+----------------------------+
(1 row)	

image.png

3.模拟一条SQL包含相同的key值

可以看到,一个SQL里插入多个行记录,并且key值相同(违反主键冲突)的时候,报了ERROR: ON CONFLICT DO UPDATE command cannot affect row a second time。上文我们也通过代码的注释部分,知道了这种问题属于用户的责任,需要用户保障,因此这部分的内容可能需要结合业务侧进行分析,检查下业务逻辑了。

postgres<16.1>(ConnAs[postgres]:PID[1103345] 2024-04-16/14:10:03)=# insert into test values (3,'hah','2024-04-16 14:01:33.640731'),(3,'hah','2024-04-16 14:01:33.640731') on conflict (id) do update set info=excluded.info,crt_time=excluded.crt_time;
ERROR:  ON CONFLICT DO UPDATE command cannot affect row a second time
HINT:  Ensure that no rows proposed for insertion within the same command have duplicate constrained values.

postgres<16.1>(ConnAs[postgres]:PID[1103345] 2024-04-16/14:10:27)=# insert into test values (4,'hah','2024-04-16 14:01:33.640731'),(5,'hah','2024-04-16 14:
01:33.640731') on conflict (id) do update set info=excluded.info,crt_time=excluded.crt_time;
INSERT 0 2
postgres<16.1>(ConnAs[postgres]:PID[1103345] 2024-04-16/14:10:38)=# select * from test;
+----+------+----------------------------+
| id | info |          crt_time          |
+----+------+----------------------------+
|  1 | test | 2024-04-16 14:09:44.405528 |
|  2 | hah  | 2024-04-16 14:01:33.640731 |
|  4 | hah  | 2024-04-16 14:01:33.640731 |
|  5 | hah  | 2024-04-16 14:01:33.640731 |
+----+------+----------------------------+
(4 rows)

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1601035.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LRTimelapse for Mac:专业延时摄影视频制作利器

LRTimelapse for Mac是一款专为Mac用户设计的延时摄影视频制作软件&#xff0c;它以其出色的性能和丰富的功能&#xff0c;成为摄影爱好者和专业摄影师的得力助手。 LRTimelapse for Mac v6.5.4中文激活版下载 这款软件提供了直观易用的界面&#xff0c;用户可以轻松上手&#…

第十五届蓝桥杯题解-好数

题目大意&#xff1a;一个数的低位为奇数&#xff0c;次低位为偶数&#xff0c;以此类推的数成为好数&#xff0c;例如&#xff1a;1&#xff0c;3&#xff0c;5&#xff0c;7&#xff0c;9 给定一个n&#xff0c;求1-n所有好数的个数&#xff0c;n<1e7 思路&#xff1a;一…

5_vscode+valgrind+gdb调试程序

需求 项目程序, 读取串口数据, 出现程序崩溃问题valgrind 可以调试定位内存问题: 内存泄漏,非法地址访问,越界访问等内存问题vscode gdb 可视化调试效果, 比命令行简单快捷很多期望使用vscode valgrind gdb 调试程序内存异常, 崩溃退出的问题 环境准备 sudo apt install v…

windows Webrtc +VS2019 (M124)下载编译以及调通测试demo

下载depot tools 设置梯子 git config --global http.proxy 127.0.0.1:10000 git config --global https.proxy 127.0.0.1:10000 下载 $ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git 设置depot_tools目录为环境变量 下载webrtc # 设置系统代…

SCADA系统通过巨控GRM模块实现OPC协议远程监控PLC

SCADA系统和PLC不在同一个地方&#xff0c;需要远程监控和控制PLC&#xff0c;可以通过巨控GRM模块来实现&#xff0c;通过OPC协议转巨控服务器远程读写PLC寄存器&#xff0c;从而完成远程监控PLC。 要实现SCAKDA系统远程监控PLC&#xff0c;关键是要实现SKADA能通过互联网访问…

【静态分析】软件分析课程实验-前置准备

课程&#xff1a;南京大学的《软件分析》课程 平台&#xff1a;Tai-e&#xff08;太阿&#xff09;实验作业平台 1. 实验概述 Tai-e 是一个分析 Java 程序的静态程序分析框架&#xff0c;相比于已有的知名静态程序分析框架&#xff08;如 Soot、Wala 等&#xff09;&#xf…

艾体宝方案 | ITT-Profitap IOTA——铁路运输的远程网络捕获和故障排除方案

在移动互联时代&#xff0c;铁路运输的数字化转型已成不可逆转的趋势。然而&#xff0c;随之而来的是对网络连接质量和故障排查的更高要求。本文将探讨如何利用艾体宝Profitap IOTA技术&#xff0c;在火车上实现远程网络捕获和故障排查&#xff0c;助力铁路运输行业迈向智能化未…

OpenStack:开源云计算的崛起与发展

目录 一&#xff0c;引言 二&#xff0c;OpenStack的起源 三&#xff0c;OpenStack的版本演进 四&#xff0c;OpenStack跟虚拟化的区别 五&#xff0c;OpenStack组件介绍 1&#xff09;Horizon介绍 2&#xff09;KeyStone介绍 Keystone 功能概览 Keystone 架构详解 3&a…

51单片机之DS1302实时时钟

1.DS1302时钟芯片介绍 DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时&#xff0c;且具有闰年补偿等多种功能RTC(Real Time Clock)&#xff1a;实时时钟&#xff0c;是一种集成电路&#xff0c;通常称…

基于stm32_h5的freertos编程示例

目录 基于stm32_h5的freertos编程示例实验目的添加FreeRTOS配置FreeRTOS测试工程本文中使用的测试工程 基于stm32_h5的freertos编程示例 本文目标&#xff1a;基于stm32_h5的freertos编程示例 按照本文的描述&#xff0c;应该可以在对应的硬件上通实验并举一反三。 先决条件…

类的加载,反射和注解详解

文章目录 类的加载概述类加载器作用分类获取类加载器的方式 双亲委派机制3种加载器的关系工作机制 类加载器的应用 反射概述关键获取类对象获取构造器对象获取方法对象获取成员变量对象作用 注解概述作用自定义注解格式属性类型 元注解常见的元注解 注解解析概述方法技巧 类的加…

LabVIEW仪器信息管理系统

LabVIEW仪器信息管理系统 在计量检测实验室的日常工作中&#xff0c;仪器检定校准是一项基础而重要的任务。随着科技的进步和实验室工作量的增加&#xff0c;传统的人工管理方式已经难以满足现代实验室对效率和准确性的要求。开发一套基于LabVIEW的仪器信息管理系统显得尤为必…

还有同学开题报告没写吗?

引言 作为一名在软件技术领域深耕多年的专业人士&#xff0c;我不仅在软件开发和项目部署方面积累了丰富的实践经验&#xff0c;更以卓越的技术实力获得了&#x1f3c5;30项软件著作权证书的殊荣。这些成就不仅是对我的技术专长的肯定&#xff0c;也是对我的创新精神和专业承诺…

Jmeter 场景测试:登录--上传--下载--登出

为了练习Jmeter的使用&#xff0c;今天我要测试的场景是“登录--上传--下载--登出”这样一个过程. 测试的目标是我曾经练手写的一个文件分享系统&#xff0c;它要求用户只有登录后才可以下载想要的文件。 Jmeter总体结构&#xff1a; 第一步&#xff1a;添加HTTP Cookie管理器…

聊聊最近两星期的学习吧!

今天是4月14号。 自从我3月份回到学校之后&#xff0c;我每天都有记录自己的学习时长。今天晚上&#xff0c;我在复盘我自己学习时长的时候&#xff0c;我发现&#xff0c;在整个四月份&#xff0c;我平均每天的有效学习时长只有6h&#xff0c;而且到今天为止&#xff0c;整个四…

Java报表是什么?盘点2023最实用的四款Java报表

从字面义就可以推知&#xff0c;Java报表指的是在Java环境下开发或使用的报表工具。Java语言因其功能强大和简单易用的特点&#xff0c;是静态面向对象编程语言的代表&#xff0c;在Java环境开发使用的这些报表工具&#xff0c;可以通过提供可视化操作界面制作报表&#xff0c;…

最新的网易星球GEC挖矿系统修复版 章鱼星球挖矿系统源码 区块链虚拟币交易源码 基于ThinkPHP5开发

区块链系统介绍 2018.12.10更新增加聚合数据短信接口 2018.11.19更新增加短信宝接口 2018.08.17修复Linux系统搭建验证码不显示问题 2018.08.09修复后台某处溢出数据库账号密码BUG 2018.08.06修复票卷BUG 源码介绍&#xff1a; 区块链系统中用户共九个等级&#xff0c;依…

LabVIEW光学探测器板级检测系统

LabVIEW光学探测器板级检测系统 特种车辆乘员舱的灭火抑爆系统广泛采用光学探测技术来探测火情。光学探测器作为系统的关键部件&#xff0c;其探测灵敏度、响应速度和准确性直接关系到整个系统的运行效率和安全性。然而&#xff0c;光学探测器在长期使用过程中可能会因为灰尘污…

怎么用手机远程控制电脑 远程控制怎么用

怎么用手机远程控制电脑&#xff1a;远程控制怎么用 在这个科技日新月异的时代&#xff0c;远程控制电脑已经成为了很多人的需求。有时&#xff0c;我们可能在外出时突然需要访问家中的电脑&#xff0c;或者在工作中需要远程操控办公室的电脑。这时&#xff0c;如果能用手机远…

力扣:141. 环形链表

力扣&#xff1a;141. 环形链表 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾…