Hands-on! 如何给 TiDB 添加新系统表
对于一个数据库开发者来说,牢固扎实的基础是十分重要的,golang学习网就来带大家一点点的掌握基础知识点。今天本篇文章带大家了解《Hands-on! 如何给 TiDB 添加新系统表》,主要介绍了MySQL、数据库,希望对大家的知识积累有所帮助,快点收藏起来吧,否则需要时就找不到了!
“TiDB,你已经是一个成熟的数据库了,该学会用自己的 SQL 查自己的状态了。”
对于一个成熟的数据库来说,通过 SQL 来查询系统本身的状态再正常不过,对于 MySQL 来说
INFOMATION_SCHEMA和
PERFORMANCE_SCHEMA里面有大量的信息,基本上通过查询些信息,DBA 就能对整个系统的运行状态一目了然。最棒的是,查询的接口正是 SQL,不需要依赖其他的第三方工具,运用表达力强大的 SQL 甚至可以对这些信息进行二次加工或者过滤,另外接入第三方的运维监控工具也很自然,不需要引入新的依赖。
过去由于种种原因,TiDB 很多的内部状态信息是通过不同组件暴露 RESTFul API 来实现,这个方案也不是不好,但是随着 API 的增多,管理成本越来越高,举一个例子:在不参考文档的前提下,用户是很难记住那么多 RESTFul API 的路径的,只能通过将这些 API 封装成命令行工具来使用,但是如果这是一张系统表,只需要一句
SHOW TABLES和几条
SELECT就能够了。当然选择 RESTFul API 还有其他的原因,例如有些操作并不是只读的,是类似命令的形式,例如:手动 split region 这类操作,使用 RESTFul API 会更好,这两者其实并不矛盾,系统表当然是一个很好的补充,这是提升整体软件易用性的一个好例子。
今天正好有一些时间,花了几十分钟完整的走了一遍流程,给 TiDB 的 INFORMATION_SCHEMA
添加了一张名为 TIDB_SERVERS_INFO
的表,用来显示集群中所有活着的 tidb-server 的状态信息(基本和 /info/all
做的事情差不多),意在抛砖引玉,社区的小伙伴可以参照这篇博客添加新的有用的信息。
有这个想法后,我的直觉是去找
information_schema的代码看看别的系统表是怎么实现的,照猫画虎就 OK 了(?没毛病)。 TiDB 的代码组织还算比较直观,在 tidb repo 的根目录下直接看到了一个包叫
infoschema,感觉就是它,打开
inforschema/table.go后确实应证了我的猜想,文件开头集中定义了很多字符串常量:
... tableTiKVStoreStatus = "TIKV_STORE_STATUS" tableAnalyzeStatus = "ANALYZE_STATUS" tableTiKVRegionStatus = "TIKV_REGION_STATUS" tableTiKVRegionPeers = "TIKV_REGION_PEERS" ...
这些常量正是 TiDB 的
INFOMATION_SCHEMA中的表名,根据这些变量顺藤摸瓜可以找到同文件里面的
tableNameToColumns这个 map,顾名思义应该是这个 map 通过表名映射到表结构定义,随便打开一个,果然如此:
var columnStatisticsCols = []columnInfo{ {"SCHEMA_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil}, {"TABLE_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil}, {"COLUMN_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil}, {"HISTOGRAM", mysql.TypeJSON, 51, 0, nil, nil}, }
下一步需要如何填充数据返回给 TiDB 的 SQL Engine,我们注意到
infoschemaTable这个类实现了
table.Table interface,很显然这个 interface 就是 TiDB 中对于 Table 获取数据/修改数据的接口,有关获取数据的方法是
IterRecords,我们只需要看到
IterRecords中的实现就能知道这些系统表的数据是如何返回给 SQL Engine 的,果然在
IterRecords里面有一个方法,
inforschemaTable.getRows(),这个方法的定义中有一个巨大的 switch 语句,用于判断是在哪个系统表上,根据这个信息然后返回不同的数据:
... switch it.meta.Name.O { case tableSchemata: fullRows = dataForSchemata(dbs) case tableTables: fullRows, err = dataForTables(ctx, dbs) case tableTiDBIndexes: fullRows, err = dataForIndexes(ctx, dbs) ... }
Bingo! 感觉就是我们需要的东西。
现在步骤就很清楚了:
- 在
infoschema/tables.go
中添加一个新的字符串常量tableTiDBServersInfo
用于定义表名; - 定义一个
[]columnInfo:tableTiDBServersInfoCols
,用于定义这张系统表的结构; - 在
tableNameToColumns
这个 map 中添加一个新的映射关系tableTiDBServersInfo => tableTiDBServersInfoCols
; - 在
infoschemaTable.getRows()
方法中加入一个新的dataForTableTiDBServersInfo
的 swtich case; - 搞定。
下一个目标是实现
dataForTableTiDBServersInfo,很显然,大致的思路是:
- 找到这个集群的 PD,因为这些集群拓扑信息;
- 将这些信息封装成
tableTiDBServersInfoCols
中定义的形式,返回给getRows
方法。
通过传入的 ctx 对象,获取到 Store 的信息,
sessionctx.Context是 TiDB 中一个很重要的对象,也是 TiDB 贯穿整个 SQL 引擎的一个设计模式,这个 Context 中间存储在这个 session 生命周期中的一些重要信息,例如我们可以通过
sessionctx.Context获取底层的 Storage 对象,拿到 Storage 对象后,能干的事情就很多了。
本着照猫画虎的原则,参考了一下
dataForTiDBHotRegions的实现:
tikvStore, ok := ctx.GetStore().(tikv.Storage)
因为我们的目标是获取 PD 对象,必然地,只有 TiKV 作为 backend 的时候才有 PD,所以这里的类型转换判断是必要的。
其实,通过 PD 获取集群信息这样的逻辑已经在 TiDB 中封装好了,我发现在
domain/info.go中的这个方法正是我们想要的:
// GetAllServerInfo gets all servers static information from etcd. func (is *InfoSyncer) GetAllServerInfo(ctx context.Context) (map[string]*ServerInfo, error)
实际上,TiDB 的
/info/all这个 REST API 正是通过调用这个函数实现,我们只需要调用这个方法,将返回值封装好就完成了。

自此,我们就完成了一个新的系统表的添加。在自己添加的新表上 SELECT 一下,是不是很有成就感 :) 欢迎大家在此基础上添加更多有用的信息。
阅读原文:https://pingcap.com/blog-cn/hands-on-build-a-new-system-table-for-tidb/

好了,本文到此结束,带大家了解了《Hands-on! 如何给 TiDB 添加新系统表》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多数据库知识!

- 上一篇
- 超详细的MySQL8.0.17版本安装教程

- 下一篇
- MAC--安装mysql及可视化工具 Navicat Premiun
-
- 花痴的烤鸡
- 这篇博文太及时了,楼主加油!
- 2023-03-25 09:46:43
-
- 淡然的萝莉
- 这篇文章太及时了,好细啊,赞 👍👍,码起来,关注up主了!希望up主能多写数据库相关的文章。
- 2023-03-24 19:59:59
-
- 正直的彩虹
- 太详细了,收藏了,感谢作者的这篇文章,我会继续支持!
- 2023-03-14 14:19:45
-
- 兴奋的小松鼠
- 这篇技术贴真及时,好细啊,很有用,码住,关注up主了!希望up主能多写数据库相关的文章。
- 2023-03-07 11:11:28
-
- 隐形的小虾米
- 很棒,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢楼主分享技术贴!
- 2023-03-06 14:49:50
-
- 数据库 · MySQL | 2天前 |
- MySQL设置中文界面,超简单教程来了!
- 332浏览 收藏
-
- 数据库 · MySQL | 2天前 | mysql 索引提示
- MySQL进阶必看!FORCE/USE/IGNOREINDEX用法大揭秘
- 182浏览 收藏
-
- 数据库 · MySQL | 2天前 |
- 手把手教你写MySQL存储过程,小白也能轻松上手
- 163浏览 收藏
-
- 数据库 · MySQL | 2天前 | mysql group by
- MySQL分组查询优化:GROUPBY原理+索引优化超全解析
- 324浏览 收藏
-
- 数据库 · MySQL | 2天前 |
- MySQL设置中文语言,轻松拥有中文界面
- 211浏览 收藏
-
- 数据库 · MySQL | 2天前 |
- MySQL建库语句从入门到精通:创建数据库+设置字符集&排序规则(附实例)
- 176浏览 收藏
-
- 数据库 · MySQL | 2天前 |
- 从零开始学MySQL数据库操作,小白轻松变大神!
- 496浏览 收藏
-
- 数据库 · MySQL | 2天前 |
- MySQL插入日期到时间字段,轻松搞定日期格式
- 484浏览 收藏
-
- 数据库 · MySQL | 2天前 | mysql 数据压缩
- MySQL怎么实现高效压缩存储?表压缩+列式存储详细解读
- 272浏览 收藏
-
- 数据库 · MySQL | 2天前 | mysql JOIN优化
- MySQL优化JOIN操作:七大技巧教你提升关联查询速度
- 106浏览 收藏
-
- 数据库 · MySQL | 2天前 |
- MySQL出现中文乱码?超详细解决方案一次性搞定
- 211浏览 收藏
-
- 数据库 · MySQL | 2天前 |
- MySQL主从复制这样配!搞懂这些参数,replication稳了~
- 131浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 茅茅虫AIGC检测
- 茅茅虫AIGC检测,湖南茅茅虫科技有限公司倾力打造,运用NLP技术精准识别AI生成文本,提供论文、专著等学术文本的AIGC检测服务。支持多种格式,生成可视化报告,保障您的学术诚信和内容质量。
- 25次使用
-
- 赛林匹克平台(Challympics)
- 探索赛林匹克平台Challympics,一个聚焦人工智能、算力算法、量子计算等前沿技术的赛事聚合平台。连接产学研用,助力科技创新与产业升级。
- 50次使用
-
- 笔格AIPPT
- SEO 笔格AIPPT是135编辑器推出的AI智能PPT制作平台,依托DeepSeek大模型,实现智能大纲生成、一键PPT生成、AI文字优化、图像生成等功能。免费试用,提升PPT制作效率,适用于商务演示、教育培训等多种场景。
- 58次使用
-
- 稿定PPT
- 告别PPT制作难题!稿定PPT提供海量模板、AI智能生成、在线协作,助您轻松制作专业演示文稿。职场办公、教育学习、企业服务全覆盖,降本增效,释放创意!
- 54次使用
-
- Suno苏诺中文版
- 探索Suno苏诺中文版,一款颠覆传统音乐创作的AI平台。无需专业技能,轻松创作个性化音乐。智能词曲生成、风格迁移、海量音效,释放您的音乐灵感!
- 60次使用
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- 搞一个自娱自乐的博客(二) 架构搭建
- 2023-02-16 244浏览
-
- B-Tree、B+Tree以及B-link Tree
- 2023-01-19 235浏览
-
- mysql面试题
- 2023-01-17 157浏览
-
- MySQL数据表简单查询
- 2023-01-10 101浏览