当前位置:网站首页>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
下一篇继续介绍这几种日志被逻辑复制解析后的情况。
边栏推荐
猜你喜欢
随机推荐
if,case,for,while
base address: environment variable
深度学习——以CNN服装图像分类为例,探讨怎样评价神经网络模型
MRS: Introduction to the use of Alluxio
打造一份优雅的简历
【Ryerson情感说话/歌唱视听数据集(RAVDESS) 】
golang中的unsafe.Pointer,指针,引用
esp8266-01s刷固件步骤
跨境电商看不到另一面:商家刷单、平台封号、黑灰产牟利
Gigabit 2 X light 8 electricity management industrial Ethernet switches WEB management - a key Ring Ring net switch
Returns the maximum number of palindromes in a string
机器学习模型的“可解释性”
STM8S105K4T6------串口发送和接收
C语言--环形缓存区
2022年最新海南建筑八大员(材料员)模拟考试试题及答案
马尔可夫链
单片机C语言->的用法,和意思
Based on the statistical QDirStat Qt directory
【MD5】采用MD5+盐的加密方式完成注册用户和登录账号
数据湖(二十):Flink兼容Iceberg目前不足和Iceberg与Hudi对比

![出现504怎么办?由于服务器更新导致的博客报504错误[详细记录]](/img/e0/32d78fac04dc2deb1cb1f847a7bab5.png)







