1.TiDB 源码阅读系列文章(十六)INSERT 语句详解
2.手把手教你实现 TiFlash 向量化函数丨十分钟成为 TiFlash Contributor
3.数据资产管理平台体系拆解(4):元数据管理
4.TiDB 源码阅读系列文章(五)TiDB SQL Parser 的源码阅读实现
5.TiFlash 源码阅读(一) TiFlash 存储层概览
TiDB 源码阅读系列文章(十六)INSERT 语句详解
作者:于帅鹏 在已有的文章《TiDB 源码阅读系列文章(四)INSERT 语句概览》中,探讨了 INSERT 语句的源码阅读基本流程。本文将深入解析 TiDB 中 INSERT 语句的源码阅读多样性,特别是源码阅读处理Unique Key冲突的各种策略。我们将了解六种不同类型的源码阅读INSERT,包括基本插入、源码阅读完整的小游戏源码忽略冲突、源码阅读更新冲突、源码阅读警告更新、源码阅读替换插入和特殊的源码阅读LOAD DATA导入。 六种INSERT语句如下:基本插入:当遇到唯一键冲突时,源码阅读返回失败。源码阅读
忽略冲突:插入时遇到冲突,源码阅读忽略并记录警告。源码阅读
更新冲突:在冲突后尝试更新并插入,源码阅读若更新后仍有冲突,报错。
警告更新:同上,冲突后更新,冲突再冲突则为警告。
替换插入:冲突时删除并插入,重复此过程直到无冲突。
LOAD DATA:类似忽略冲突,数据来自csv文件,但处理方式特殊。
基本插入的执行逻辑在executor/insert.go,其中InsertExec实现了Executor接口。执行流程根据是否使用SELECT语句获取数据,分为insertRows和insertRowsFromSelect。insertOneRow是处理基本插入的核心部分,它在事务提交时检查冲突,利用batchChecker进行高效冲突检测。 对于INSERT IGNORE,虽然基本插入在提交时检测冲突,但INSERT IGNORE需要立即检测,因此使用batchChecker实现批量检查,以提高效率。而INSERT ON DUPLICATE KEY UPDATE更为复杂,涉及插入和更新操作,通过batchChecker读取和更新数据,处理各种可能的冲突情况。 REPLACE INSERT语句则具有特殊性,它会删除冲突行直到成功插入,这与其它INSERT语句处理冲突的方式有所不同。 理解这些INSERT语句的实现,对于使用TiDB的高效执行以及潜在的代码贡献具有重要意义。继续阅读源码,掌握这些细节,将有助于你更准确地运用INSERT语句。图像傅里叶变换源码手把手教你实现 TiFlash 向量化函数丨十分钟成为 TiFlash Contributor
本文作者:黄海升,TiFlash 研发工程师
TiFlash 的开源获得了社区的广泛关注,很多开发者通过阅读源码来理解 TiFlash 的设计原理,并且有不少人渴望参与到 TiFlash 的贡献中来。为了帮助大家快速成为 TiFlash 的贡献者,我们特此撰写一系列文章,从理论到实践,与大家分享关于 TiFlash 的一切。
在前篇中,我们简单介绍了如何将 TiDB 函数下推到 TiFlash,以及在开发过程中需要掌握的一些基础知识。本篇将带领你亲手实现一个向量化函数,具体步骤如下:
在 TiDB 的代码库中,你需要在 expression/expression.go 文件中找到 scalarExprSupportedByFlash 方法,并添加你的函数,以便 TiDB 的 planner 可以判断该函数是否可以下推到 TiFlash。
为了验证下推逻辑,需要在 expression/expr_to_pb_test.go 文件中添加针对你的函数的单元测试,并在 planner/core/integration_test.go 文件中增加对应的集成测试。你可以参考已有的测试案例,如 TestRightShiftPushDownToTiFlash,来构建你的测试用例。确保你的测试用例能够验证函数是否正确地被下推到 TiFlash 算子中。
在 TiFlash 的代码库中,你需要了解相关的前置知识,包括 TiFlash 的向量化计算、IFunction 接口、数据类型体系、Column 体系以及使用 C++ 模板简化类型处理。在实现下推时,要根据函数的类型添加映射,并选择合适的实现逻辑。
为了确保你的函数功能正确,需要编写并运行单元测试。在 TiFlash 的 README 文件中,你可以找到如何在本地运行测试的详细说明。通常,你需要先以 DEBUG 模式构建代码,然后运行特定目录下的测试脚本,如 dbms/gtests_dbms、libdaemon/src/tests/gtests_libdaemon 和 libcommon/src/tests/gtests_libcommon。
最后,进行集成测试以确保你的函数能够在实际的 TiFlash 环境中正常工作。测试脚本通常位于 /tests 目录下,这将帮助你验证函数与 TiFlash 的其他组件之间的交互。
通过遵循上述步骤,你将能够实现一个向量化函数,并成为 TiFlash 的在线pdf转换 源码有效贡献者。我们希望这一系列文章能成为你学习和贡献 TiFlash 的指南,共同推动 TiDB 生态系统的发展。
数据资产管理平台体系拆解(4):元数据管理
阅读本文需要分钟,以数据之名,践资产之行。
1、以数据之名 简介
2、元数据的基本概念
2.1 抽象概念
元数据,简单来说就是描述数据的数据。元数据无处不在,换言之有数据存在,就有其对应元数据。完整、准确的元数据存在,有助于更好地理解数据本体,充分挖掘数据的价值。
单存的从概念来讲,确实比较抽象,我们对元数据的理解还是很模糊。那么让我们先看一段简历达人"张三"的个人简历。
这份简历中的"电话"、"工作经验"、"年龄"、"邮箱"、"教育背景"等对于张三本人的关键描述信息,就是元数据,因为它们是用来描述具体数据/信息的数据/信息。这样引用论证的方式,是不是让我们对元数据的概念一瞬间立体起来啦。
2.2 具体概念
对于企业应用的具体概念,元数据是企业所使用的物理数据、业务流程、数据结构等有关的信息,描述了数据(如数据库、数据模型)、概念(如业务流程、应用系统、技术架构)以及它们之间的关系。
元数据管理是对数据采集、存储、加工和展现等数据全生命周期的描述信息,帮助用户理解数据关系和相关属性。
3、元数据的价值
通过元数据管理,形成整个系统信息数据资产的精准视图,通过元数据的统一视图,缩短数据清理周期、提高数据质量以便能系统性地管理数据中心项目中来自各业务系统的源码里面的mdb海量数据,梳理业务元数据之间的关系,建立信息数据标准完善对这些数据的解释、定义,形成企业范围内一致、统一的数据定义,并可以对这些数据来源、运作情况、变迁等进行跟踪分析。
元数据是企业数据资产的基础应用字典和操作指南,元数据管理有利于统一数据口径、标明数据方位、分析数据关系、管理数据变更,为企业级的数据治理提供支持,是企业实现数据自服务、推动企业数据化运营的可行路线。
4、元数据分类
4.1 业务元数据
4.2 管理元数据
4.3 技术元数据
描述对象存储的元数据,也是通常"狭义"上的元数据,包括几大类:
描述离线或实时ETL任务数据计算过程的元数据。
描述数据质量的一类元数据。
描述数据是如何进行使用的一类元数据。
描述系统运维层面的元数据,通常包括以下几类。
描述数据存储及计算成本的元数据。
描述数据标准化内容的元数据。
描述数据安全内容的元数据。
描述数据是如何共享的部分,通常使用以下几种方式:
5、元数据管理办法
5.1 关键活动
5.2 管理流程
我们可以采用角色与组织联动,制定一套标准化元数据管理流程体系,贯穿于整个数据采集、管理分析与数据服务端到端的实施过程,来完善整体的元数据管理体系。
6、元数据管理功能
6.1 元数据采集
元数据管理平台通过不同的数据采集适配器,能支持从不同的数据源中采集从生产业务系统、数据中转系统、数据应用系统等端到端应用链路的数据流转过程的全量元数据,包括过程中的数据实体(系统、库、表、字段的描述)以及数据实体加工处理过程中的逻辑元数据。同时还能制定采集任务定时采集,减少人工操作的IT成本。
6.2 元数据访问
元数据访问服务是元数据管理软件提供的元数据访问的接口服务,一般支持Http、文件、openwrt源码装软件接口库等对接形式。通过元数据访问服务支持企业元数据的共享,是企业数据治理的基础。
6.3 元数据管理
实现元数据的模型定义并存储,在功能层包装成各类元数据功能,最终对外提供应用及展现;提供元数据分类和建模、血缘关系和影响分析,方便数据的跟踪和回溯。
6.4 元数据分析
元数据的应用一般包括数据地图、数据血缘分析、关联性分析、影响分析、全链分析等,分析出元数据的来龙去脉,快速识别元数据的价值,掌握元数据变更可能造成的影响,以便更有效的评估变化带来的风险,从而帮助用户高效准确的对数据资产进行清理、维护与使用。
7、元数据管理功能架构
备注:权限管理中心,走平台统一鉴权SSO
8、元数据血缘解析
8.1 血缘解析引擎构建
基于数据资产开发平台作为开发统一入口的前提,构建元数据血缘引擎服务体系。引擎体系:SQL、Kettle 、Xml、Excel、Interface、Service、Workflow 、Datax等任务体系:DMP(Datax任务、SQL任务、Shell任务、报表任务、监控任务)、KMP(Kettle任务)、DMS(接口和服务)、BMP(工作流和调度器)等目标方向:基于血缘解析引擎解析落地元数据,提供可视化的标准ETL任务元数据血缘查询服务,以及KMP/DMP/BMP三大平台任务关联性和影响性分析服务。
8.2 血缘解析引擎机制
基于DMP数据管理开发平台,快速实施个性化报表开发的端到端流程图,其中任务开发、血缘查询和血缘确认环节为开发人员手动实施流程,其余环节为平台系统自动化实施流程,具体如下图所示:
9、元数据功能预览
9.1 血缘分析
9.2 影响分析
9.3 全链分析
9.4 关联度分析
9.5 元数据全文检索
、数据平台文章集锦
数据资产管理平台体系拆解(1):“平台概述”
数据资产管理平台体系拆解(2):“系统分解”
数据资产管理平台体系拆解(3):“数据模型”
MySQL死磕到底系列第一篇“围城之困”
MySQL死磕到底系列第二篇“破冰之旅”
MySQL死磕到底系列第三篇“踏浪之途”
MySQL死磕到底系列第四篇“刨根之程”
MyCAT来生续缘第三篇
无Hive,不数仓
基于Hive+HBase双引擎完善数据仓库更新机制
基于TiDB构建高性能综合数据服务平台
基于Kettle快速构建基础数据仓库平台
金融数据仓库之分层命名规范
一入数据深似海,集市仓库湖中台
湖不湖实战系列之Hudi构建湖仓一体架构
湖不湖实战系列之Hudi源码编译
湖不湖实战系列之Spark2部署升级
湖不湖实战系列之Spark2构建HDFS到Hudi通路
湖不湖实战系列之Spark2构建Hive到Hudi通路
BI选型哪家强,以数据之名挑大梁
数仓小白快速成长为技术专家视频资料集合
小编心声 虽小编一己之力微弱,但读者众星之光璀璨。小编敞开心扉之门,还望倾囊赐教原创之文,期待之心满于胸怀,感激之情溢于言表。一句话,欢迎联系小编投稿您的原创文章! 让我们携手成为技术专家
参考资料
[1] 元数据分类参考1: baijiahao.baidu.com/s?...
[2] 元数据分类参考2: baijiahao.baidu.com/s?...
[3] 数据资产白皮书5.0:中国信通院
[4] Markdown模板: product.mdnice.com/arti...
TiDB 源码阅读系列文章(五)TiDB SQL Parser 的实现
本文是 TiDB 源码阅读系列文章的第五篇,主要内容围绕 SQL Parser 功能实现进行讲解。内容源自社区伙伴马震(GitHub ID:mz)的投稿。系列文章的目的是与数据库研究者及爱好者深入交流,收到了社区的积极反馈。后续,期待更多伙伴加入 TiDB 的探讨与分享。
TiDB 的源码阅读系列文章,帮助读者系统性地学习 TiDB 内部实现。最近的《SQL 的一生》一文,全面阐述了 SQL 语句处理流程,从接收网络数据、MySQL 协议解析、SQL 语法解析、查询计划制定与优化、执行直至返回结果。
其中,SQL Parser 的功能是将 SQL 语句按照 SQL 语法规则进行解析,将文本转换为抽象语法树(AST)。此功能需要一定背景知识,下文将尝试介绍相关知识,以帮助理解这部分代码。
TiDB 使用 goyacc 根据预定义的 SQL 语法规则文件 parser.y 生成 SQL 语法解析器。这一过程可在 TiDB 的 Makefile 文件中看到,通过构建 goyacc 工具,使用 goyacc 依据 parser.y 生成解析器 parser.go。
goyacc 是 yacc 的 Golang 版本,因此理解语法规则定义文件 parser.y 及解析器工作原理之前,需要对 Lex & Yacc 有所了解。Lex & Yacc 是用于生成词法分析器和语法分析器的工具,它们简化了编译器的编写。
下文将详细介绍 Lex & Yacc 的工作流程,以及生成解析器的过程。我们将从 Lex 根据用户定义的 patterns 生成词法分析器,词法分析器读取源代码并转换为 tokens 输出,以及 Yacc 根据用户定义的语法规则生成语法分析器等角度进行阐述。
生成词法分析器和语法分析器的过程,用户需为 Lex 提供 patterns 的定义,为 Yacc 提供语法规则文件。这两种配置都是文本文件,结构相同,分为三个部分。我们将关注中间规则定义部分,并通过一个简单的例子来解释。
Lex 的输入文件中,规则定义部分使用正则表达式定义了变量、整数和操作符等 token 类型。例如整数 token 的定义,当输入字符串匹配正则表达式时,大括号内的动作会被执行,将整数值存储在变量yylval 中,并返回 token 类型 INTEGER 给 Yacc。
而 Yacc 的语法规则定义文件中,第一部分定义了 token 类型和运算符的结合性。四种运算符都是左结合,同一行的运算符优先级相同,不同行的运算符,后定义的行具有更高的优先级。语法规则使用 BNF 表达,大部分现代编程语言都可以使用 BNF 表示。
表达式解析是生成表达式的逆向操作,需要将语法树归约到一个非终结符。Yacc 生成的语法分析器使用自底向上的归约方式进行语法解析,同时使用堆栈保存中间状态。通过一个表达式 x + y * z 的解析过程,我们可以理解这一过程。
在这一过程中,读取的 token 压入堆栈,当发现堆栈中的内容匹配了某个产生式的右侧,则将匹配的项从堆栈中弹出,将该产生式左侧的非终结符压入堆栈。这个过程持续进行,直到读取完所有的 tokens,并且只有启始非终结符保留在堆栈中。
产生式右侧的大括号中定义了该规则关联的动作,例如将三项从堆栈中弹出,两个表达式相加,结果再压回堆栈顶。这里可以使用 $position 的形式访问堆栈中的项,$1 引用第一项,$2 引用第二项,以此类推。$$ 代表归约操作执行后的堆栈顶。本例的动作是将三项从堆栈中弹出,两个表达式相加,结果再压回堆栈顶。
在上述例子中,动作不仅完成了语法解析,还完成了表达式求值。一般希望语法解析的结果是一颗抽象语法树(AST),可以定义语法规则关联的动作。这样,解析完成时,我们就能得到由 nodeType 构成的抽象语法树,对这个语法树进行遍历访问,可以生成机器代码或解释执行。
至此,我们对 Lex & Yacc 的原理有了大致了解,虽然还有许多细节,如如何消除语法的歧义,但这些概念对于理解 TiDB 的代码已经足够。
下一部分,我们介绍 TiDB SQL Parser 的实现。有了前面的背景知识,对 TiDB 的 SQL Parser 模块的理解会更易上手。TiDB 使用手写的词法解析器(出于性能考虑),语法解析采用 goyacc。我们先来看 SQL 语法规则文件 parser.y,这是生成 SQL 语法解析器的基础。
parser.y 文件包含 多行代码,初看可能令人感到复杂,但该文件仍然遵循我们之前介绍的结构。我们只需要关注第一部分 definitions 和第二部分 rules。
第一部分定义了 token 类型、优先级、结合性等。注意 union 结构体,它定义了在语法解析过程中被压入堆栈的项的属性和类型。压入堆栈的项可能是终结符,也就是 token,它的类型可以是 item 或 ident;也可能是非终结符,即产生式的左侧,它的类型可以是 expr、statement、item 或 ident。
goyacc 根据这个 union 在解析器中生成对应的 struct。在语法解析过程中,非终结符会被构造成抽象语法树(AST)的节点 ast.ExprNode 或 ast.StmtNode。抽象语法树相关的数据结构定义在 ast 包中,它们大都实现了 ast.Node 接口。
ast.Node 接口有一个 Accept 方法,接受 Visitor 参数,后续对 AST 的处理主要依赖这个 Accept 方法,以 Visitor 模式遍历所有的节点以及对 AST 做结构转换。例如 plan.preprocess 是对 AST 做预处理,包括合法性检查以及名字绑定。
union 后面是对 token 和非终结符按照类型分别定义。第一部分的最后是对优先级和结合性的定义。文件的第二部分是 SQL 语法的产生式和每个规则对应的 aciton。SQL 语法非常复杂,大部分内容都是产生式的定义。例如 SELECT 语法的定义,我们可以在 parser.y 中找到 SELECT 语句的产生式。
完成语法规则文件 parser.y 的定义后,使用 goyacc 生成语法解析器。TiDB 对 lexer 和 parser.go 进行封装,对外提供 parser.yy_parser 进行 SQL 语句的解析。
最后,我们通过一个简单的例子,使用 TiDB 的 SQL Parser 进行 SQL 语法解析,构建出抽象语法树,并通过 visitor 遍历 AST。我实现的 visitor 只输出节点的类型,运行结果依次输出遍历过程中遇到的节点类型。
了解 TiDB SQL Parser 的实现后,我们有可能实现当前不支持的语法,如添加内置函数。这为我们学习查询计划以及优化打下了基础。希望这篇文章对读者有所帮助。
作者介绍:马震,金蝶天燕架构师,负责中间件、大数据平台的研发,今年转向 NewSQL 领域,关注 OLTP/AP 融合,目前在推动金蝶下一代 ERP 引入 TiDB 作为数据库存储服务。
TiFlash 源码阅读(一) TiFlash 存储层概览
本系列文章聚焦于 TiFlash,读者需具备基本的 TiDB 知识。TiFlash 是 TiDB HTAP 模式的关键组件,作为 TiKV 的列存扩展,通过 Raft Learner 协议实现异步复制,并提供与 TiKV 相同的快照隔离支持。自 5.0 引入 MPP 后,TiDB 的实时分析场景下计算加速能力得到了增强。
TiFlash 整体逻辑模块划分如下:通过 Raft Learner Proxy 接入多 Raft 体系,计算层 MPP 在 TiFlash 间进行数据交换,提供更强的分析计算能力。Schema 模块与 TiDB 表结构同步,将 TiKV 同步数据转换为列形式,并写入列存引擎。底层为 DeltaTree 引擎。
TiFlash 基于 ClickHouse fork,沿用了 ClickHouse 的向量化执行引擎,并加入针对 TiDB 的对接、MySQL 兼容、Raft 协议、集群模式、实时更新列存引擎、MPP 架构等特性。DeltaTree 引擎解决了高频率数据写入、实时更新读性能优化、符合 TiDB 事务模型、支持 MVCC 过滤、数据分片便于分析场景等需求。
DeltaTree 引擎不同于 MergeTree,具备原生支持高频率写入、列存实时更新下读性能优化、支持 TiDB 事务模型、数据分片便于提供分析特性等优势。MergeTree 引擎存在写入碎片、Scan 时 CPU cache miss 严重、清理过期数据时 compaction 导致性能波动等问题,而 DeltaTree 通过横向分割数据管理、delta-stable 数据组织、PageStorage 存储等设计优化了性能。
DeltaTree 引擎通过在表内按 handle 列分段管理数据,采用 delta-stable 数据组织,PageStorage 存储小数据块,构建 DeltaIndex 和 Rough Set Index 等组件优化读性能。DeltaIndex 帮助减少 CPU bound 的 merge 操作,Rough Set Index 用于过滤数据块,减少不必要的 IO 操作。
TiFlash 存储层 DeltaTree 引擎在不同数据量和更新 TPS 下读性能表现优于基于 MergeTree 的实现,提供更稳定、高效的读、写性能。TiFlash 中的 PageStorage、DeltaIndex、Rough Set Index 等组件协同作用,优化数据管理和查询性能。
DeltaTree 引擎在 TiFlash 内部实现中,通过 PageStorage 存储数据,DeltaIndex 提高读性能,Rough Set Index 优化查询效率,提供了对 HTAP 场景的优化和支持。TiFlash 存储层 DeltaTree 引擎的设计和实现细节将在后续章节中详细展开。