当前位置:网站首页>Postgresql源码(66)insert on conflict语法介绍与内核执行流程解析
Postgresql源码(66)insert on conflict语法介绍与内核执行流程解析
2022-08-04 03:30:00 【mingjie73】
1 语法介绍
insert on conflict语法实现了upsert的功能,即在插入发生主键冲突、或唯一约束冲突时,执行on conflict后面的语句,将insert变成update或do nothing避免报错。
语法手册:https://www.postgresql.org/docs/current/sql-insert.html
测试用例:
drop table decoding_test;
CREATE TABLE decoding_test(x integer primary key, y text);
postgres=# select * from decoding_test;
x | y
----+---
12 | 9
postgres=# INSERT INTO decoding_test(x,y) values(12,9) on conflict (x) do nothing;
INSERT 0 1
postgres=# select * from decoding_test;
x | y
----+---
12 | 9
-- 没有报主键冲突,结果上看插入没有效果。
postgres=# INSERT INTO decoding_test(x,y) values(12,9) on conflict (x) do nothing;
INSERT 0 0
postgres=# select * from decoding_test;
x | y
----+---
12 | 9
(1 row)
postgres=# INSERT INTO decoding_test(x,y) values(101,20) on conflict (x) do update set y=EXCLUDED.y;
INSERT 0 1
postgres=#
postgres=# select * from decoding_test;
x | y
-----+----
12 | 9
101 | 20
-- 插入时发生主键冲突,执行后面的update语句,将y更新为400,EXCLUDED表示准备要新插入的这一行数据。
postgres=# INSERT INTO decoding_test(x,y) values(101,400) on conflict (x) do update set y=EXCLUDED.y;
INSERT 0 1
postgres=# select * from decoding_test;
x | y
-----+-----
12 | 9
101 | 400
(2 rows)
2 内核执行流程
注意:后面提到的
speculative insert
等价与insert on conflict语法
。
2.1 从执行流程观察speculative insert
执行流程:
- spec insert的执行流程和普通insert是分开的,走两个分支。
- spec比较特殊的就是有重试机制,即:
- 在第一次检查如果没发现有唯一键冲突,正常是可以直接insert的。
- 但由于无锁检查,可能在真正insert时又发生了唯一键冲突(前面检查完了,其他并发insert一条冲突数据)
- 那么这时xlog中已经有一条成功的insert了,需要再后面加一条delete(图中第四步冲突发生了)。
2.2 从日志角度观察speculative insert
INSERT INTO decoding_test(x,y) values(12,9) on conflict (x) do nothing;
- 情况一:插入成功
- heap_insert,生成XLOG_HEAP_INSERT日志。
- heap_finish_speculative,生成XLOG_HEAP_CONFIRM日志。
- 情况二:插入失败
- 不生成日志
- 情况三:插入时还没有冲突,但其他进程并发插入冲突行(并发冲突位置在后面分析)
- heap_insert,生成XLOG_HEAP_INSERT日志。
- heap_abort_speculative,生成XLOG_HEAP_DELETE日志。
- 情况一:插入成功
INSERT INTO decoding_test(x,y) values(20,9) on conflict (x) do update set y=100;
- 插入成功
- heap_insert,生成XLOG_HEAP_INSERT日志。
- heap_finish_speculative,生成XLOG_HEAP_CONFIRM日志。
- 更新成功:转换为update语句执行
- log_heap_update,生成XLOG_HEAP_HOT_UPDATE日志。
- 插入时还没有冲突,但其他进程并发插入冲突行(并发冲突位置在后面分析)
- heap_insert,生成XLOG_HEAP_INSERT日志。
- heap_abort_speculative,生成XLOG_HEAP_DELETE日志。
- 插入成功
所以从日志中可能看到3种情况:
情况一: 第一条XLOG_HEAP_INSERT 第二条XLOG_HEAP_CONFIRM
情况二: 第一条XLOG_HEAP_INSERT 第二条XLOG_HEAP_DELETE
情况三: 第一条XLOG_HEAP_HOT_UPDATE
下一篇继续介绍这几种日志被逻辑复制解析后的情况。
边栏推荐
猜你喜欢
C language -- ring buffer
系统太多,多账号互通如何实现?
三分建设,七分管理!产品、系统、组织三管齐下节能降耗
MySQL query optimization and tuning
6口全千兆二层网管型工业以太网交换机千兆2光4电光纤自愈ERPS环网交换机
Based on the statistical QDirStat Qt directory
汇编语言之栈
Y86. Chapter iv Prometheus giant monitoring system and the actual combat, Prometheus storage (17)
[Study Notes Dish Dog Learning C] Dynamic Memory Management
跨境电商看不到另一面:商家刷单、平台封号、黑灰产牟利
随机推荐
Mini program + new retail, play the new way of playing in the industry!
Y86. Chapter iv Prometheus giant monitoring system and the actual combat, Prometheus storage (17)
哎,又跟HR在小群吵了一架!
Returns the maximum number of palindromes in a string
力扣(LeetCode)215. 数组中的第K个最大元素(2022.08.03)
千兆2光8电管理型工业以太网交换机WEB管理X-Ring一键环网交换机
Exclude_reserved_words 排除关键字
SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropri
缓存穿透、缓存击穿、缓存雪崩以及解决方案
出现504怎么办?由于服务器更新导致的博客报504错误[详细记录]
Power button (LeetCode) 215. The first K largest elements in the array (2022.08.03)
元宇宙“吹鼓手”Unity:疯狂扩局,悬念犹存
内网服务器访问远程服务器的端口映射
C语言--环形缓存区
How to read the resources files in the directory path?
Mockito单元测试
如果禁用了安全启动,GNOME 就会发出警告
初识Numpy
一个属于程序员的七夕节!
JVM内存和垃圾回收-07.堆