postgresql内核源码分析-删除表drop table流程

news2024/10/5 22:22:39

 

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

目录

前言

调用关系

概要流程

详细流程

创建对象列表空间

删除多个指定的数据库对象(performMultipleDeletions)

对于普通表,最终调用heap_drop_with_catalog删除表元数据和文件

在事务结束时的动作真正删除磁盘文件

结尾


前言

本文是基于postgresql 15的代码进行分析解读,演示是在centos8系统上进行。介绍了内核源码中关于DDL中drop table的处理流程。在删除表时,如何做到删除表物理文件与的事务原子性。


调用关系

生成执行计划后,调用standard_ProcessUtility进行执行,其中计划节点类型为T_DropStmt。

case T_DropStmt:

ExecDropStmt((DropStmt *) parsetree, isTopLevel);

/* no commands stashed for DROP */

commandCollected = true;

break;

在执行层调用ExecDropStmt进行实际执行。

概要流程

/*

 * Dispatch function for DropStmt

 */

static void

ExecDropStmt(DropStmt *stmt, bool isTopLevel)

{

switch (stmt->removeType)

{

case OBJECT_INDEX:

if (stmt->concurrent)

PreventInTransactionBlock(isTopLevel,

  "DROP INDEX CONCURRENTLY");

/* fall through */



case OBJECT_TABLE:

case OBJECT_SEQUENCE:

case OBJECT_VIEW:

case OBJECT_MATVIEW:

case OBJECT_FOREIGN_TABLE:

RemoveRelations(stmt);

break;

default:

RemoveObjects(stmt);

break;

}

}

可以看到删除数据库对象被分成了三种情况,表/索引等关系对象调用RemoveRelations。

ExecDropStmt调用,这里index/table/foreign table/view/materialized view/sequence都是调用这里。对于删除表的主要流程如下:

(1)对于concurrent删除索引判断,如果是的话,需要加一些较弱的锁;调用关系ExecDropStmt;

(2)判断删除的对应类型; 调用关系ExecDropStmt->RemoveRelations;

(3)建立删除对象的列表,并且锁定每张表;调用关系ExecDropStmt->RemoveRelations;

(4)依据列表检查依赖并生成报告,再删除对象;调用关系ExecDropStmt->RemoveRelations->performMultipleDeletions;

(5)释放对角列表空间,调用关系ExecDropStmt->RemoveRelations->free_object_addresses;

详细流程

  • 创建对象列表空间

ObjectAddresses *

new_object_addresses(void)

{

ObjectAddresses *addrs;



addrs = palloc(sizeof(ObjectAddresses));



addrs->numrefs = 0;

addrs->maxrefs = 32;

addrs->refs = (ObjectAddress *)

palloc(addrs->maxrefs * sizeof(ObjectAddress));

addrs->extras = NULL;                /* until/unless needed */



return addrs;

}

这里初始最大可以有32个对象,后面添加时,不够时会再进行扩展。

  • 删除多个指定的数据库对象(performMultipleDeletions)

(1)如果指定了CASCADE,就会递归删除依赖的对象;

(2)如果指定为RESTRICT,则当遇到依赖时会报错;

删除的模式可以有以下几种:

PERFORM_DELETION_INTERNAL, 删除操作不是由用户直接发起;比如临时schema的删除;目前此模式下会事件触发器和权限检查不会被调用。

PERFORM_DELETION_CONCURRENTLY,仅用于index,进行concurrently delete;

PERFORM_DELETION_QUIETLY,会减少日志打印

PERFORM_DELETION_SKIP_ORIGINAL,仅仅删除指定对象的依赖对象,该指定对象不删除;

PERFORM_DELETION_SKIP_EXTENSIONS,用于删除临时对象,当对象是扩展的一部分时,只删对象而不删除扩展;

PERFORM_DELETION_CONCURRENT_LOCK,用于REINDEX CONCURRENTLY,在删除时加concurrent lock;

其中调用,deleteObjectsInList-> deleteOneObject进行真正的删除动作。

deleteOneObject

(1)对于concurrently模式,需要先关闭pg_depend系统表,在(2)删除后再次打开;

(2)调用doDeletion进行删除对象;

(3)删除pg_depend中的依赖数据行;

(4)删除comments,security labels, privilages;

(5)CommandCounterIncrement,变更可见性;

doDeletion根据class类型,调用对应的接口

  • 对于普通表,最终调用heap_drop_with_catalog删除表元数据和文件

heap_drop_with_catalog的流程如下:

(1)从syscache中获取表信息,查看是否为分区表;是分区表的话,要锁定父表;

(2)打开表加8级表锁,也就是最高级表锁;下面开始删除操作;

(3)检查串行化冲突;

(4)如果是外部表,打开pg_foreign_table并删除表元数据,并从syscache中删除;

(5)分区表时,删除表对应的分区键;如果是默认分区,需要更新默认分区;

(6)删除表的文件,添加到待删除列表中,在提交时统一删除,子事务的汇集到父事务提交时统一删除;

(7)删除表的统计信息,也是在提交时统一删除;

(8)关闭表,此时不需要解锁;在事务提交时会自动释放;

(9)删除订阅关系映射,从pg_subscription_rel中查询删除元组;

(10)忘记该表的提交时的行为记录;

(11)刷新relcache数据字典缓存,确保没有被引用或引时被重建;

(12)移除继承关系,从pg_inherits删除对应元组;

(13)从pg_statistic中删除统计信息;

(14)删除属性,pg_attribute中的相关元组;

(15)最后从pg_class中删除表的相关元组;

(16)对于分区表,更新默认分区和父表的元数据缓存;对于它们是update操作;

  • 在事务结束时的动作真正删除磁盘文件

CommitTransaction

->smgrDoPendingDeletes(true)

当然在abort时也会调用,但是传参为false不会删除;


结尾

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

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

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

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

相关文章

【蓝桥杯国赛真题27】Scratch LED屏幕 少儿编程scratch图形化编程 蓝桥杯国赛真题讲解

目录 scratch LED屏幕 一、题目要求 编程实现 二、案例分析 1、角色分析

C#中使用git将项目代码上传到远程仓库的操作

一、远程仓库创建操作(远程仓库使用的是gitHub) 1、登录GitHub官网,注册登录账号后,点击创建仓库 2、仓库名称命名,如下所示: 3、创建成功如下所示:获得https协议(https://github.c…

Android开发不可缺少的辅助工具

目录 jadxandroid_toolscrcpy-guiCode CraftsSQLite Expert Personal jadx jadx是一款apk反编译工具。 PS:部分版本安装,无法打开类文件,需换个版本。 开源地址:https://github.com/skylot/jadx android_tool android_tool可以通…

【瑞萨RA_FSP】SCL UART 串口通信

文章目录 一、串口通信协议简介1. 物理层2. 协议层 二、SCI 简介三、SCI的结构框图四、UART波特率计算 一、串口通信协议简介 串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,因此大部分电子设备都支持该通讯方式&a…

SNAT和DNAT策略

文章目录 1.SNAT策略及应用1.1 SNAT原理与应用1.2 SNAT策略的工作原理1.3 实验步骤 2.DNAT策略2.1 DNAT策略的概述2.1 DNAT原理与应用2.3 实验步骤 3.规则的导出、导入4. 总结 1.SNAT策略及应用 1.1 SNAT原理与应用 SNAT 应用环境:局域网主机共享单个公网IP地址接…

【利用AI让知识体系化】关于浏览器内核的基础知识

I. 介绍 什么是浏览器内核 浏览器内核(Browser Engine),也叫浏览器渲染引擎(Rendering Engine),是浏览器的核心组成部分,它负责将 HTML、CSS、JavaScript 等代码经过解析和渲染后,…

End-to-End Object Detection with Transformers 论文学习

论文地址:End-to-End Object Detection with Transformers 1. 解决了什么问题? 现有的目标检测算法需要大量的人为先验的设计,如 anchor 和 NMS,整体架构并不是端到端的。现有的检测方法为了去除重叠框,一般会利用 p…

企业级信息系统开发——初探Spring - 利用组件注解符精简Spring配置文件

文章目录 一、打开项目二、利用组件注解符精简Spring配置文件(一)创建新包(二)复制四个类(三)修改杀龙任务类(四)修改救美任务类(五)修改勇敢骑士类&#xff…

NEEPU Sec 2023 公开赛 writeup

文章目录 WebCute CirnoCute Cirno(Revenge) RevHow to use ida?BaseHow to use python?IKUN检查器junk code CryptoFunnyRsaLossloud Misc吉林第一站倒影Shiro重生之我是CTFer 问卷 Web Cute Cirno 学艺不精的我脑袋要炸了 在Cirno界面的源代码中发现任意读 考虑之前的比…

在Ubuntu20.04部署Flink1.17实现基于Flink GateWay的Hive On Flink的踩坑记录(一)

在Ubuntu20.04部署Flink1.17实现基于Flink GateWay的Hive On Flink的踩坑记录(一) 前言 转眼间,Flink1.14还没玩明白,Flink已经1.17了,这迭代速度还是够快。。。 之前写过一篇:https://lizhiyong.blog.c…

View中的滑动冲突

View中的滑动冲突 1.滑动冲突的种类 滑动冲突一般有3种, 第一种是ViewGroup和子View的滑动方向不一致 比如: 父布局是可以左右滑动,子view可以上下滑动 第二种 ViewGroup和子View的滑动方向一致 第三种 第三种类似于如下图 2.滑动冲突的解决方式 滑动冲突一般情况下有2…

Ubuntu 20.04上安装和配置Samba

介绍: Samba是一个开源的软件套件,它允许不同操作系统之间共享文件和打印机。在Ubuntu 20.04上安装和配置Samba是一种方便的方法,可以在本地网络中共享文件夹,使多台计算机能够轻松访问共享文件。本文将向您展示如何在Ubuntu 20.0…

Properties使用

Properties是一种特殊的文本文件,可用来存储配置文件,或者存储一些键值对格式的数据信息 一、底层原理 分析源码可知,Properties底层实现是Map 二、创建&常用方法&遍历 1、创建 // 创建Properties对象 Properties properties …

设置Ubuntu 20.04的静态IP地址

引言:我们做嵌入式或者其他的项目时,有时候不免发现,Ubuntu的ip地址经常会改变,这个时候就需要我们手动配置静态IP了。 给Ubuntu设置一个静态IP地址有以下几个好处: 持久性:静态IP地址是固定不变的&#xf…

一.RxJava

1.RxJava使用场景 RxJava核心思想 Rx思维:响应式编程,从起点到终点,中途不能断掉,并且可以在中途添加拦截. 生活中的例子: 起点(分发事件,我饿了)->下楼->去餐厅->点餐->终点(吃饭,消费事件) 程序中的例子: 起点(分发事件,点击登录)->登录API->请求服务器-…

Lucene(3):Lucene全文检索的流程

1 Lucene准备 Lucene可以在官网上下载:Apache Lucene - Welcome to Apache Lucene。我们使用的是7.7.2版本,文件位置如下图: 使用这三个文件的jar包,就可以实现lucene功能 2 开发环境准备 JDK: 1.8 (Luce…

python 面向对象--类,对象,属性,方法,魔法方法

1.理解面向对象思想 面向过程思想: 遇到问题,分析步骤.按照步骤解决问题.(复杂,重复) 面向对象思想: 遇到问题,找到能解决问题的对象去解决.(简单,复用) 2.类和对象 # 定义类的格式: # class 类名(): # 代码 # ......class Student(): ​def study(self):print(学生好…

【连续介质力学】Voigt符号

Voigt符号 一个对称二阶张量有6个独立的分量,那么就可以将他表示成列向量的形式: 这种表示方式为Voigt符号,也可以将二阶张量表示成: 正如minor对称的四阶张量C, C i j k l C j i k l C i j l k C j i l k C_{ij…

hive函数

函数 Hive的函数分为两大类∶内置函数(Built-in Functions )、用户定义函数UDF (User-Defined Functions ) . 内置函数可分为︰数值类型函数、日期类型函数、字符串类型函数、集合函数、条件函数等; 用户定义函数根据输入输出的行数可分为3类:UDF、UDAF、UDTF。 UDF:普通函…

一图看懂 charset_normalizer 模块:字符集规范化,真正的第一个通用字符集检测器,资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创,转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 charset_normalizer 模块:字符集规范化,真正的第一个通用字符集检测器,资料整理笔记(大全) 🧊摘要&a…