【StoneDB研发日志】列式存储 delete方案调研

MySQL删除数据的方式

以MySQL 5.7为例,数据库删除数据的方式一共有以下三种:

  1. delete
  2. truncate
  3. drop

三种方式都可以删除数据,但使用场景有所不同。

[En]

Data can be deleted in all three ways, but the usage scenarios are different.

对于删除整个表的速度:

[En]

For the speed at which the entire table is deleted:

drop > truncate >> delete

MySQL删除数据的方式-delete

delete是属于数据库的DML操作语言,一般是根据条件逐行进行删除。
使用delete删除数据时,数据库只能删除数据不能删除表的结构,并且会触发数据库的事务机制。
delete执行时,会先将所删除数据缓存到rollback segment中,事务commit之后生效;
在InnoDB中,使用delete其实并不会真正的把数据删除,是一种逻辑删,数据库底层实际上只是给删除的数据做了一个已删除的标记,因此,删除数据后的表占空间大小和删除前是一样的.

MySQL删除数据的方式-drop

drop属于数据库DDL定义语言,同 truncate ,执行后立即生效,无法找回。
drop table table_name立刻释放磁盘空间 ,drop 语句将删除表的结构、被依赖的约束(constraint)、触发器(trigger)、索引(index); 依赖于该表的存储过程/函数将保留,但是变为 invalid 状态。

删除数据的方式-TianMu 引擎的支持情况

目前StoneDB的TianMu引擎是支持 truncate 语句 和 drop 语句的,但是delete语句目前还不支持。

TianMu引擎需要不需要delete?

TianMu引擎设计的初衷

TianMu是一个列式存储引擎,列式存储的出现主要是为了方便快捷查询和高效存储大量同类型的数据而设计的,主要使用场景就是OLAP场景。下面是OLAP场景的部分关键特征:
①绝大多数是读请求
②数据以相当大的批次(> 1000行)更新,而不是单行更新;或者根本没有更新。
无法修改③已添加到数据库中的数据。

[En]

Data that ③ has added to the database cannot be modified.

对于读取,④从数据库中提取相当数量的行,但只提取一小部分列。

[En]

For reads, ④ extracts a considerable number of rows from the database, but only a small portion of the columns.

⑤列中的数据相对较小:数字和短字符串(例如,每个URL 60个字节)
⑥在处理单个查询时需要高吞吐量(每个服务器每秒几十亿行)

[En]

⑥ requires high throughput when processing a single query (billions of rows per server per second)

⑦事务不是必须的
⑧对数据一致性要求低

目前行业现状

支持列存储的数据库类型 是否支持delete 备注

MariaDB ColumnStore 支持 SQL Server 支持 Oracle In-Memory Column Store 支持 DB2 BLU Acceleration 支持 MySQL HeatWave 不支持 主要作为辅助引擎,支持DML同步 TiFlash 不支持 主要作为辅助引擎,支持DML同步 PolarDBIn-Memory Column Index 支持 openGauss 支持 ClickHouse 支持 非标准的DELETE操作

OLAP场景下 对于数据的delete的操作可以说没有或者频率很小,同时列式存储对比行式存储来说并不擅长数据的增删改,如果是为了极致的查询性能,完全可以舍弃 DML 操作。但是为了功能的完整性,提升产品的竞争力,目前我们也放开了 insert 和 单表的 update 的功能,delete功能暂时还不支持,未来我们将对改功能进行支持。

主流列式数据库的delete方案

本节主要讲以下三种列式存储数据库的delete方案:
openGauss
ClickHouse
PolarDB

openGauss 列存储引擎的方案

底层存储结构

openGauss底层存储结构与stonedb类似 ,存储基本单位是CU(Compression Unit,压缩单元),即表中一列的一部分数据组成的压缩数据块。行存引擎中是以行作为单位来管理,而当使用列存储时,整个表整体被按照不同列划分为若干个CU。

【StoneDB研发日志】列式存储 delete方案调研
CU文件本身结构,则如下图所示。
【StoneDB研发日志】列式存储 delete方案调研
每个CU对应一个CU Desc的记录,在CU desc里记录了整个CU的事务时间戳信息、CU的大小、存储位置、magic校验码、min/max等信息。
【StoneDB研发日志】列式存储 delete方案调研
每张列存表还配有一张Delta表,Delta表自身为行存储表。当有少量的数据插入到一张列存表时,数据会被暂时放入Delta表,等到到达阈值或满足一定条件或操作时再行整合为CU文件。Delta表可以避免单点数据操作带来的很重的CU操作与开销。

删除策略

  • 列存储的CU中数据的删除,实际上是标记删除。删除操作,相当于是更新了CUDesc表中CU对应CUDesc记录的delete bitmap(删除位图)结构,标记列中某行对应数据已被删除,而CU文件数据不会被更改。这样可以避免删除操作带来的IO放大以及解压、压缩的高额CPU开销。这样的设计,也可以使得对于同一个CU的select(查询)和delete(删除)互不阻塞,提升并发能力。列存储CU中数据更新,则是遵循append-only(仅允许追加)原则的,即CU文件仅会向后进行延展扩充,亦或是启用新的CU文件,而不是在对应行在CU中的位置就地更新。

【StoneDB研发日志】列式存储 delete方案调研

失效空间的清理

  • 由于CU以及CUDesc的元数据管理模式,原有系统中的Vacuum机制实际上并不会非常有效的清除CU中已经失效的存储空间,因为Lazy Vacuum(清理数据时,只是标识无用行的状态可以录入新数据,不会影响对表数据的操作)仅能在CUDesc级别进行操作,在多数场景下无法对CU文件本身进行清理。列存储内部如果要对列存数据表进行清理,需要执行Vacuum Full(除了清理无用行,还会合并数据块,整个过程会锁定表)操作。

ClickHouse delete 方案

特点:缺乏修改或删除现有数据的高频、低延迟能力。只能用于批量删除或修改数据。

[En]

Features: lack of high-frequency, low-latency ability to modify or delete existing data. Can only be used to bulk delete or modify data.

数据有序存储
ClickHouse支持在建表时,指定将数据按照某些列进行sort by。排序后,保证了相同sort key的数据在磁盘上连续存储,且有序摆放。在进行等值、范围查询时,where条件命中的数据都紧密存储在一个或若干个连续的Block中,而不是分散的存储在任意多个Block, 大幅减少需要IO的block数量。另外,连续IO也能够充分利用操作系统page cache的预取能力,减少page fault。

【StoneDB研发日志】列式存储 delete方案调研

delete 策略

ClickHouse是个分析型数据库。
OLAP场景下,数据一般是不变的,因此ClickHouse对update、delete的支持是比较弱的,实际上并不支持标准的update、delete操作。
ClickHouse通过alter方式实现更新、删除,它把update、delete操作叫做mutation(突变)。
标准SQL的更新、删除操作是同步的,即客户端要等服务端返回执行结果(通常是int值);
而ClickHouse的update、delete是通过异步方式实现的,当执行update语句时,服务端立即返回,但是实际上此时数据还没变,而是排队等着。
Mutation具体过程
首先,使用where条件找到需要修改的分区;然后,重建每个分区,用新的分区替换旧的,分区一旦被替换,就不可回退;对于单独一个分区,是原子性的;但对于整个mutation,如果涉及多个分区,则不是原子性的。

PolarDB In-Memory Column Index

特点:PolarDB将列存实现为InnoDB的二级索引
在PolarDB中所有Primary Index和Secondary Index都实现为一个B+Tree。列索引在定义上是一个Index,但其实是一个虚拟的索引,用于捕获对该索引覆盖列的增删改操作。

【StoneDB研发日志】列式存储 delete方案调研
如上图所示,在PolarDB中所有Primary Index和Secondary Index都实现为一个B+Tree。而列索引在定义上是一个Index,但其实是一个虚拟的索引,用于捕获对该索引覆盖列的增删改操作。
对于上面的表其主表(Primary Index)包含(C1,C2,C3,C4,C5) 5列数据, Seconary Index索引包含(C2,C1) 两列数据, 在普通二级索引中,C2与C1编码成一行保存在B+tree中。而其中的列存索引包含(C2,C3,C4)三列数据. 在实际物理存储时,会对三列进行拆分独立存储,每一列都会按写入顺序转成列存格式。
列存实现为二级索引的另一个好处是执行器的工程实现非常简单,在MySQL中已经存在覆盖索引的概念,即一个查询所需要的列都在一个二级索引中存储,则可以直接利用这个二级索引中的数据满足查询需求,使用二级索引相对于使用Primary Index可以极大减少读取的数据量进而提升查询性能。当一个查询所需要的列都被列索引覆盖时,借助列存的加速作用,可以数十倍甚至数百倍的提升查询性能。

实现为InnoDB二级索引方案的优点:

1.查询执行器的工程实现非常简单
2.可以复用InnoDB的事务处理框架
3.可以复用InnoDB的数据编码格式
4.DDL语句操作非常灵活
5.可以复用InnoDB的Redo事务日志模块
6.二级索引与主表有一样的生命周期,方便管理

列存数据组织

对ColumnIndex中每一列,其存储都使用了无序且追加写的格式,结合标记删除及后台异步compaction实现空间回收。其具体实现上有如下几个关键点:
列索引中记录按RowGroup进行组织,每个RowGroup中不同的列会各自打包形成DataPack。
每个RowGroup都采用追加写,分属每个列的DataPack也是采用追加写模式。对于一个列索引,只有个Active RowGroup负责接受新的写入。当该RowGroup写满之后即冻结,其包含的所有Datapack会转为压缩格保存到磁盘上,同时记录每个数据块的统计信息便于过滤。
列存RowGroup中每新写入一行都会分配一个RowID用作定位,属于一行的所有列都可以用该RowID计算定位,同时系统维护PK到RowID的映射索引,以支持后续的删除和修改操作。
删除操作只需要设置一个删除标志位。

[En]

The delete operation requires only one delete flag bit to be set.

更新操作采用标记删除的方式来支持,对于更新操作,首先根据RowID计算出其原始位置并设置删除标记,然后在ActiveRowGroup中写入新的数据版本。
当一个RowGroup中的无效记录超过一定阈值,则会触发后台异步compaction操作,其作用一方面是回收空间,另一方面可以让有效数据存储更加紧凑,提升分析型查询单的效率。

【StoneDB研发日志】列式存储 delete方案调研

delete 策略

删除操作只需要设置一个删除标志位。

[En]

The delete operation requires only one delete flag bit to be set.

更新操作采用标记删除的方式来支持,对于更新操作,首先根据RowID计算出其原始位置并设置删除标记,然后在ActiveRowGroup中写入新的数据版本。
当一个RowGroup中的无效记录超过一定阈值,则会触发后台异步compaction操作,其作用一方面是回收空间,另一方面可以让有效数据存储更加紧凑,提升分析型查询的效率。

各列式存储的delete方案汇总

支持列存储的数据库类型 存储结构 Delete策略

MariaDB ColumnStore 固定大小的数据块+元数据 标记删除 SQL Server 列存储索引+行组+列段 标记删除 PolarDB In-Memory Column Index 列存储索引+RowGroup+DataPack+元数据 标记删除 openGauss 元数据+数据包 标记删除 ClickHouse 有序存储+分区数据包 新建分区替换

TianMu引擎 delete 功能规划

GitHub issue 链接:
https://github.com/stoneatom/stonedb/issues/343

【StoneDB研发日志】列式存储 delete方案调研

TianMu引擎 delete 功能实现流程图

【StoneDB研发日志】列式存储 delete方案调研

Original: https://www.cnblogs.com/yangwilly/p/16591997.html
Author: 来来士
Title: 【StoneDB研发日志】列式存储 delete方案调研

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/505016/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • JUC学习笔记(二)

    1.1、Synchronized synchronized 是 Java 中的关键字,是一种同步锁。它修饰的对象有以下几种: 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的…

    数据库 2023年6月6日
    0128
  • 如何使用原生的Feign

    什么是Feign Feign 是由 Netflix 团队开发的一款基于 Java 实现的 HTTP client,借鉴了 Retrofit、 JAXRS-2.0、WebSocket…

    数据库 2023年6月6日
    0188
  • 2022-8-18 第六组 JDBC

    JDBC 1. 概念:Java DataBase Connectivity Java 数据库连接, Java语言操作数据库 JDBC本质:其实是官方(sun公司)定义的一套操作所有…

    数据库 2023年6月14日
    0138
  • Vue 3.x基础

    Vue 3.x基础 模版 <template> // html </template> <script setup> // setup API …

    数据库 2023年6月11日
    0142
  • Github 星标 8K+ 这款国人开源的 Redis 可视化管理工具,真香…

    做程序员就少不了与一些工具打交道,比如:监控工具、管理工具等,有些工具是命令行界面,有些工具是可视化界面,反正都是可以能够满足日常使用的功能需求。 对于redis管理工具来说,也有…

    数据库 2023年6月9日
    0185
  • zabbix监控配置流程

    zabbix监控配置流程 管理层次: 开发人员要加监控,需要让其提供监控指标运营人员要加监控,让其找开发要监控指标运维人员要加监控,让运营人员去找开发要监控指标。 配置层次: 1….

    数据库 2023年6月14日
    0144
  • SQL Server解惑——为什么你拼接的SQL语句换行符失效了?

    –========================================================================================…

    数据库 2023年6月11日
    0150
  • MySQL 主从同步延迟监控

    MySQL5.7和8.0支持通过 replication_applier_status 表获同步延迟时间,当从库出现延迟后,该表中的字段 REMAINING_DELAY 记录延迟秒…

    数据库 2023年6月11日
    0147
  • [springmvc]拦截器功能

    11.拦截器 只会拦截controller的请求,对于静态资源不处理 被spring代理的拦截器实现只需要两步: 1.实现一个拦截器类 package com.spring.con…

    数据库 2023年6月16日
    0129
  • 719. 找出第 K 小的数对距离

    数对 (a,b) 由整数 a 和 b 组成,其数对距离定义为 a 和 b 的绝对差值。 给你一个整数数组 nums 和一个整数 k ,数对由 nums[i] 和 nums[j] 组…

    数据库 2023年6月16日
    0170
  • 2022-8-17 mysql 第三天

    子查询 根据结果集中的行数,子查询可以分为以下几类: [En] According to the number of rows in the result set, subquer…

    数据库 2023年5月24日
    098
  • centos7安装python

    以下操作均在root用户下进行(防止权限不够的问题)一、查看centos自带的python(python -v)因为centos自带的是python2.7的版本 二、安装自己想装的…

    数据库 2023年5月24日
    0155
  • Mysql索引底层数据结构与算法

    一.索引概述是什么:索引是帮助MySQL高效获取数据的排好序的数据结构,索引叫”键”,优化好一个索引,可以提高数倍的性能, 类似于字典的音序表为什么要键索引…

    数据库 2023年6月11日
    0172
  • 如何画出别人一看就懂的架构图?

    技术传播的价值,不仅仅体现在通过商业化产品和开源项目来缩短我们构建应用的路径,加速业务的上线速率,也体现在优秀工程师在工作效率提升、产品性能优化和用户体验改善等经验方面的分享,以提…

    数据库 2023年6月14日
    0158
  • Matery主题自定义(一)黑夜模式

    黑夜模式 作为一个前端学习者,自然懂得黑夜模式的重要性,可惜主题原生未提供,那就自己弄吧 参考其他优秀产品的黑夜模式,得出共性: 那就是黑夜模式的背景一般不会是纯黑(#000);而…

    数据库 2023年6月16日
    0113
  • java面试题(2022最新)

    JDK 和 JRE 有什么区别?JRE:Java Runtime Environment(java运行时环境)。即java程序的运行时环境,包含了java虚拟机,java基础类库。…

    数据库 2023年6月16日
    0132
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球