头图

开务数据库delete流程解读

开务数据库delete语句delete from table where xxx的执行流程为:

delete主要分为两个部分,一个部分为scan过程,拉取表中的数据,第二部分,根据过滤条件,调用b.Del()函数删除对应的数据。相关逻辑计划对象图为:

deleteNode下包含一个scanNode,负责拉取表中数据,deleteRun包括实际执行delete操作的信息,包括表中数据的索引信息,事务相关信息txn,batch…,还有tabledesc等等信息。

其中在构建逻辑计划时,有一个maybeCreateDeleteFastNode函数,来判断是否可以执行deleterange操作,判断条件为:

1.表中是否具有索引,如果有,不可以执行deleterange

2.该表是否为交错表,如果是,不可以执行deleterange

3.该表主键是否关联了其他表的外键,如果是,不可以执行deleterange

4.renderNode下是否为scanNode,如果不是,不可以执行deleterange

5.过滤条件没有被下推为span,不可以执行deleterange

6.有limit关键字时,不可以执行deleterange

在满足以上过滤条件后,如果可以执行deleterange,就会把其中的deleteNode转化为deleteRangeNode,在执行时,rowCountNode的startExec会直接调用到deleteRangeNode的startExec,通过直接下发对span的DelRange操作来删除数据,不会调用到BatchNext中。

deleteRange过程部分代码:

spans := make([]roachpb.Span, len(d.spans))
    copy(spans, d.spans)
    for len(spans) != 0 {
        b := params.p.txn.NewBatch()
        for _, span := range spans {
            if traceKV {
                log.VEventf(ctx, 2, "DelRange %s - %s", span.Key, span.EndKey)
            }
            b.DelRange(span.Key, span.EndKey, true /* returnKeys */)
        }
        b.Header.MaxSpanRequestKeys = TableTruncateChunkSize
 
        if err := params.p.txn.Run(ctx, b); err != nil {
            return err
        }
 
        spans = spans[:0]
        for _, r := range b.Results {
            var prev []byte
            for _, keyBytes := range r.Keys {
                // If prefix is same, don't bother decoding key.
                if len(prev) > 0 && bytes.HasPrefix(keyBytes, prev) {
                    continue
                }
 
                after, ok, err := d.fetcher.ReadIndexKey(keyBytes)
                if err != nil {
                    return err
                }
                if !ok {
                    return pgerror.NewAssertionErrorf("key did not match descriptor")
                }
                k := keyBytes[:len(keyBytes)-len(after)]
                if !bytes.Equal(k, prev) {
                    prev = k
                    d.rowCount++
                }
            }
            if r.ResumeSpan != nil && r.ResumeSpan.Valid() {
                spans = append(spans, *r.ResumeSpan)
            }
        }
    }

KaiwuDB 是浪潮集团控股的数据库企业,公司汇聚了全球顶尖的数据库人才,以多模数据库为核心产品,面向...

9 声望
1 粉丝
0 条评论
推荐阅读
KaiwuDB 荣获第三届 ISIG 产业智能大会年度最佳技术创新奖
3月17日,由中国某部电子化标准研究院、苏州金融科技协会、中国计算机用户协会指导,多单位共同举办参与的「第三届中国 ISIG 产业智能大会」在上海召开。

KaiwuDB阅读 81

万字详解,吃透 MongoDB!
MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统,由 C++ 编写的。MongoDB 提供了 面向文档 的存储方式,操作起来比较简单和容易,支持“无模式”的数据建模,可以存储比较复杂的数据类型,是一款非常...

JavaGuide8阅读 1.7k

封面图
万字长文~vue+express+mysql带你彻底搞懂项目中的权限控制(附所有源码)
所谓的权限,其实指的就是:用户是否能看到,以及是否允许其对数据进行增删改查的操作,因为现在开发项目的主流方式是前后端分离,所以整个项目的权限是后端权限控制搭配前端权限控制共同实现的

水冗水孚11阅读 1.5k

花了几个月时间把 MySQL 重新巩固了一遍,梳理了一篇几万字 “超硬核” 的保姆式学习教程!(持续更新中~)
MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一。

民工哥11阅读 1.1k

封面图
一次偶然机会发现的MySQL“负优化”
今天要讲的这件事和上述的两个sql有关,是数年前遇到的一个关于MySQL查询性能的问题。主要是最近刷到了一些关于MySQL查询性能的文章,大部分文章中讲到的都只是一些常见的索引失效场合,于是我回想起了当初被那个...

骑牛上青山8阅读 2.3k评论 2

源码编译安装Postgresql 11.4
postgresql版本: 11.4(因为12还是beta版)2 准备工作2.1 安装gcc编辑器 {代码...} gcc用于编译源码2.2 安装make {代码...} make用于批量编译链接源码,实际干活的还是gcc2.3 安装readline {代码...} readline是...

SHIYIBODEC1阅读 8.4k

程序员英语学习指南
动机为什么程序员要学习英语?工作:我们每天接触的代码都是英文的、包括很多技术文档也是英文的学习:最新最前沿的技术最开始都是只有English版本就业:学好英语让你的就业范围扩大到全球,而不只限于国内目标读...

九旬6阅读 685

KaiwuDB 是浪潮集团控股的数据库企业,公司汇聚了全球顶尖的数据库人才,以多模数据库为核心产品,面向...

9 声望
1 粉丝
宣传栏