postgresql insert ddl执行流程分析

news2024/12/23 14:34:52

 

  • 专栏内容:postgresql内核源码分析
  • 个人主页:我的主页
  • 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

目录

前言

总体流程

调用堆栈

执行接口说明

详细流程分解

ExecInsert对于普通表的insert;

插入tuple的流程,调用table_tuple_insert(heapam_tuple_insert)中;

heap_insert的流程:

索引创建过程简述

结尾


前言

本文是基于postgresql 15的代码进行分析解读,演示是在centos8系统上进行。


总体流程

(1)如果是分区表,需要找到对应子表;

(2)待插入表是否有索引,需要打开对应的索引表;

(3)处理before row insert triggers

(4)处理instead of row insert triggers

(5)如果是Fdw(foreign-data wrapper)接口的表,单独处理

(6)处理tuple检查和insert buffer

(7)如果是分区表,引起分区key变化,导致有tuple要移动到新分区时,处理数据的delete/insert;

(8)处理after row insert triggers

(9) 处理with check option;

(10) 生成returning

调用堆栈

ExecInsert(ModifyTableState * mtstate, ResultRelInfo * resultRelInfo, TupleTableSlot * slot, TupleTableSlot * planSlot, EState * estate, _Bool canSetTag)

ExecModifyTable(PlanState * pstate)

ExecProcNode(PlanState * node)

ExecutePlan(_Bool execute_once, DestReceiver * dest, ScanDirection direction, uint64 numberTuples, CmdType operation, _Bool use_parallel_mode, PlanState * planstate, EState * estate)

standard_ExecutorRun(QueryDesc * queryDesc, ScanDirection direction, uint64 count, _Bool execute_once)

ProcessQuery(PlannedStmt * plan, const char * sourceText, ParamListInfo params, QueryEnvironment * queryEnv, DestReceiver * dest, QueryCompletion * qc)

PortalRunMulti(Portal portal, _Bool isTopLevel, _Bool setHoldSnapshot, DestReceiver * dest, DestReceiver * altdest, QueryCompletion * qc)

PortalRun(Portal portal, long count, _Bool isTopLevel, _Bool run_once, DestReceiver * dest, DestReceiver * altdest, QueryCompletion * qc)

exec_simple_query(const char * query_string)

PostgresMain(const char * dbname, const char * username)

BackendRun()

BackendStartup()

ServerLoop()

PostmasterMain(int argc, char ** argv)

main(int argc, char ** argv)

在经过SQL解析,生成执行plan后,就开始调用PortalRun进行执行阶段,最后调用ExecutePlan,按照plan中的每个node进行执行,不同的node有不同的类型,比如merge/sort等等(详细参见本专栏的执行计划分享),每种类型有对应的执行调用,对于insert的执行动作,主要由ExecInsert来完成。

执行接口说明

static TupleTableSlot *

ExecInsert(ModifyTableContext *context,

           ResultRelInfo *resultRelInfo,

           TupleTableSlot *slot,

           bool canSetTag,

           TupleTableSlot **inserted_tuple,

           ResultRelInfo **insert_destrel)

slot,中存储有需要insert的tuple;

**inserted_tuple,插入成功后的tuple;

**inserted_destrel,是出参,新tuple插入成功后的表,因为这里有可能是不同的分区表;

插入不成功函数返回值为NULL。

详细流程分解

postgresql在整个处理时,进行分层处理,这里涉及到了两层:

一是执行层,对应的调用是ExecInsert

二是heapam层,也就是针对heap类型表的操作;这里是为了支持多种类型表而留了扩展设计的空间;heapam层对应的调用是table_tuple_insert

  • ExecInsert对于普通表的insert;

(1)如果有自动生成列,进行数据生成;

(2)with check option类型判断和处理;

(3)检查约束

(4)检查分区表约束,是否符合分区条件;

(5)是否有冲突处理策略,如果有需要检查处理;

(6)如果没有冲突处理策略,则正常插入tuple和创建索引;

  • 插入tuple的流程,调用table_tuple_insert(heapam_tuple_insert)中;

(1)从slot记录的tuple数据,拼装成要插入的tuple;

(2)获取table OID

(3)调用heap_insert,查找空闲空间将tuple插入page,记录wal等;

(4)将插入的tuple的tid记录到slot;方便后面进行索引的插入;

(5)如果有申请tuple空间,在这里释放;

  • heap_insert的流程:

(1)准备tuple,在拼装好的tuple上继续填写infomask/xmin/xmax等;对于可压缩的,当前tup大于toast存储阈值时,要拼成toast存储tuple;

(2)查找有空闲空间的buffer来插入当前tuple;同时检查是否都可见,标记vm文件;(查找空闲空间的流程请查看本专栏的文章)

(3)检查串行化级别的冲突;

(4)开启关键代码区;将tuple放到buffer中;

(5)更新可见性信息;

(6)标脏buffer;

(7)写WAL日志;结束关键代码区;

(8)释放buffer,vmbuffer;

(9)如果插入的是系统表的tuple,需要invalidatecache;

(10)记录t_cid给返回者,释放申请的tuple;

  • 索引创建过程简述

(1)在tuple插入成功后,得到tuple的tid;

(2)调用ExecInsertIndexTuples,执行indextuple的插入;这是在执行层的调用;

(3)每张表可以有多个index,所以扫描数据字典,查找有多少个索引;然后每个索引进行分别插入;

(4)对于每个索引,调用对应的Indexam层接口进行处理;这里调用index_insert,它内部调用indexRelation->rd_indam->aminsert,这是在创建索引时初始化好的。索引相关详细内容查看本专栏的内容。


结尾

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。

注:未经同意,不得转载!

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

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

相关文章

Java9

Java9 (一)、stream流1.1 Stream流的中间方法和终结方法 (二)、方法引用2.1 方法引用的分类 (三)、异常3.1 编译时异常和运行时异常3.2 异常的作用3.3 异常的处理方式3.4 异常中的常见方法3.5 自定义异常 &…

麒麟设置分辨率

为什么要设置------额。。。。虚拟机启动的,直接满屏了。。。。也不能移动 命令设置法 1、可以通过xrandr命令来设置屏幕分辨率。先查询当前分辨率,及当前支持的分辨率。 xrandr 2、可以通过-s参数来设置为1920x1440 xrandr -s 1920x1440 这就好…

Midjouney prompt优化

Midjouney prompt优化 总述1. Midjouney1.1 常见出图方式1.2 图片参数 2. prompt2.1 prompt关键词框架逻辑2.2 关键词技巧2.3 分类关键词2.3.1 媒体类型、介质和渲染引擎2.3.2 艺术风格2.3.2.1常见风格关键词2.3.2.2 艺术风格介绍2.3.2.3 绘画风格关键词和作品 2.3.3 相机镜头和…

面试官从这些方面考察你的Android开发水平!

View基础(25题) 什么是ViewView的位置参数MotionEventViewRootDecorViewMeasureSpec View三大流程(28题) measure过程ViewViewGrouplayout过程draw过程获取View的宽高Activity启动到加载ViewRoot的流程 自定义View(26题) 四种实现方法直接继承View自定义属性直接继承ViewG…

C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”

C的一个大坑:菱形继承 希望这篇文章能让你理解什么是菱形继承,以及菱形继承的注意事项 单继承与多继承 单继承:一个子类只有一个直接父类时称这个继承关系为单继承 多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承…

【半监督学习】Match系列.2

本文简单介绍半监督算法中的Match系列方法:CoMatch(ICCV2021),CRMatch(GCPR2021),Dash(ICML2021),UPS(ICLR2021),SimMatch…

ajax、fetch、axios三者的异同

同:都是发送网络请求 异: 1.ajax ajax是异步的javascript和xml,用于创建快速的动态网页的技术。(用js发送异步的网络请求) 特点:局部刷新页面,无需重载整个页面。 很多小伙伴会误以为ajax是…

2023年的深度学习入门指南(12) - PEFT与LoRA

2023年的深度学习入门指南(12) - PEFT与LoRA 大家都知道,大模型的训练需要海量的算力。其实,即使是只对大模型做微调训练,也是需要大量的计算资源的。 有没有用更少的计算资源来进行微调的方法呢?研究者研发出了几种被Hugging F…

fastCGI使用

1.http解释 在使用fastCGI之前需要先了解什么是http,以及静态请求和动态请求。 1.什么是http HTTP是超文本传输协议,它定义了客户端和服务器端之间文本传输的规范。HTTP通常运行在TCP之上,使用80端口。HTTP是一种简单的请求-响应协议&#x…

GUN C编译器拓展语法学习笔记(二)属性声明

一、属性声明 1、存储段:section 1.1 GNU C编译器扩展关键字:__attribute__ GNU C增加了一个__attribute__关键字用来声明一个函数、变量或类型的特殊属性。主要用途就是指导编译器在编译程序时进行特定方面的优化或代码检查。例如,我们可以…

C语言三子棋小游戏

哈喽,大家好,今天我们要利用之前所学习的C语言知识来写一个三子棋小游戏。 目录 1.游戏 2.函数部分 2.1.菜单 2.2.初始化棋盘 2.3.打印棋盘 2.4.玩家下棋 2.5.电脑下棋 2.6.判断输赢 2.7.判断棋盘是否已满 3.完整代码展示 1.游戏 今天我们写的…

未知时间信息下雷达运动目标的计算高效重聚焦与估计方法

论文背景 在雷达成像中,回波信号在接收到之前可能已经被多次反射或散射,这样会导致回波信号的时间和频率发生变化。其中,距离向维度上的变化称为距离单元迁移(range cell migration,RCM),频率向…

Spring笔记

文章目录 1、什么是Spring?2、如何创建Spring3、Spring简单的读和取操作1.直接在spring-config.xml里面放置对象2.通过配置扫描路径和添加注解的方式添加Bean对象3.为什么需要五个类注解4.从spring中简单读取 Bean对象5.Resource和Autowired的异同 1、什么是Spring&…

Transformer结构细节

一、结构 Transformer 从大的看由 编码器输入、编码器、解码器、解码器输入和解码器输出构成。 编码器中包含了词嵌入信息编码、位置编码、多头注意力、Add&Norm层以及一个全连接层; 解码器中比编码器多了掩码的多头注意力层。 二、模块 2.1 Input Embeddi…

canvas学习之华丽小球滚动电子时钟

教程来自 4-3 华丽的小球滚动效果 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>华丽小球滚动时钟…

【AVL树的模拟实现】

1 AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下。因此&#xff0c;两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年发明了一种解决…

人工智能基础部分14-蒙特卡洛方法在人工智能中的应用及其Python实现

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能基础部分14-蒙特卡洛方法在人工智能中的应用及其Python实现&#xff0c;在人工智能领域&#xff0c;蒙特卡洛方法&#xff08;Monte Carlo Method, MCM&#xff09;被广泛应用于各种问题的求解。本文首先将…

wvp-GB28181-pro录像功能开发环境搭建、配置、使用

开发环境、调试环境搭建 开发wvp平台搭建 离线安装脚本&#xff1a;https://gitcode.net/zenglg/ubuntu_wvp_online_install.git 下载离线安装脚本&#xff0c;完成wvp平台的部署 开发环境要求 操作系统&#xff1a;包管理工具是apt ky10桌面版uos桌面版deepin桌面版ubuntu桌面…

ArmDot.NET Crack

ArmDot.NET Crack ArmDot是一个.NET加密工具&#xff0c;用于保护使用.NET编写的程序。 企业需要保护他们的知识产权&#xff0c;包括他们的算法、产品和使用的资源的源代码。 然而&#xff0c;.NET编译器会生成一个通用的可访问代码。代码中嵌入的资源很容易访问&#xff0c;并…

RocketMQ不同的类型消息

目录 普通消息 可靠同步发送 可靠异步发送 单向发送 三种发送方式的对比 顺序消息 事物消息 两个概念 事务消息发送步骤 事务消息回查步骤 消息消费要注意的细节 RocketMQ支持两种消息模式: 普通消息 RocketMQ提供三种方式来发送普通消息&#xff1a;可靠同步发送、…