GreatSQL社区

搜索

[讨论中] 【实测】GreatSQL 8.4.4-5 元数据接口:和其他兼容引擎对照

1425 8 2026-9-23 18:47
本帖最后由 LibreDB 于 2026-9-23 18:49 编辑

利益相关先说清楚:我们在做一个开源的数据库 IDE,里面有走 MySQL 协议的驱动。这篇是今天刚把 GreatSQL 拉起来,用同一套探针跑出来的,不是照文档抄的。最后一条是我们自己写错的地方。
环境:greatsql/greatsql:latest,version() 报 8.4.4-5,@@version_comment 是 GreatSQL, Release 5, Revision 39b389cdf3b。docker 单机,两张探针表(3 行 / 2000 行 / 6000 行)。
先说结论:我们踩过的坑,GreatSQL 一个都没踩我们一共连了 42 种数据库,其中不少号称"兼容 MySQL 协议"。做客户端的人最怕的就是那些接口在、答案却是假的的情况。下面这几项,在别的兼容引擎上挨个挂过,GreatSQL 全部正常:
接口GreatSQL 8.4.4-5我们在别处踩的坑
version()8.4.4-5,真话StarRocks 答 5.1.0、Doris 答 5.7.99,都是不存在的版本
SHOW STATUS LIKE '...'正常,Uptime / Threads_connected 都有Doris 语法直接解析不过(mismatched input 'LIKE')
max_connections512Doris 和 StarRocks 都不发布这个变量
information_schema.PROCESSLIST2 行,正常StarRocks 根本没有这张表,会话面板和健康检查一起挂
performance_schema123 张表,其中 5 张是 replication_group_*OceanBase 的租户里没有这个库,健康检查过不去
information_schema.statistics4 行,索引全报出来了Doris 和 StarRocks 永远是空的,一个索引都报不出来
EXPLAIN FORMAT=JSON正常返回 JSONDoris 和 StarRocks 都解析不过,只能退回裸 EXPLAIN
KILL QUERY接受Vitess 的 vtgate 拒绝,跑着的查询杀不掉
ANALYZE / OPTIMIZE / CHECK三个都在Doris 的语法里压根没有 OPTIMIZE 和 CHECK
外键:可见,而且真的生效这一条单独拎出来,因为差别最大。
ALTER TABLE probe_orders ADD CONSTRAINT fk_cust  FOREIGN KEY (customer_id) REFERENCES probe_customers(id);· information_schema.KEY_COLUMN_USAGE 里有这一行,所以 ER 图画得出来;
· 插一条引用不存在客户(424242)的订单:ERROR 1452 (23000) ... a foreign key constraint fails。
对照 Doris:同样的语句被接受,SHOW CONSTRAINTS 也列得出来,但 KEY_COLUMN_USAGE 是 0 行(图画不出来),而且那条脏数据插进去了——那里的外键是优化器提示,不是约束。
INDEX_LENGTH 是 0,不是 NULL看起来是小事,其实不是。我们对 DATA_LENGTH + INDEX_LENGTH 求和算表大小,StarRocks 对每张 BASE TABLE 的 INDEX_LENGTH 答 NULL,NULL 把整个和变成 NULL,于是表大小永远读 0。
GreatSQL 这里答的是实打实的 0(probe_lag 没有二级索引)或真实字节数,求和不会被污染。
唯一真正会坑到工具的一条:表大小是偏小的这条得说清楚,而且不是 GreatSQL 的锅,是 MySQL 8.x 一脉相承的行为——但做工具的人必须知道。
第一层:统计信息不会自己追上来。
probe_lag 插了 2000 行,information_schema.tables 立刻读:
table_rows = 2000   data_length = 16384行数对了,大小是建表时的初始值。等了 90 秒,一个字节都没变。 跑一次 ANALYZE TABLE 才变成 98304。
这和 TiDB、Doris 是两种形状:那两个也会先读 0,但一分钟左右自己会对,是延迟;GreatSQL 这里不 ANALYZE 就一直是旧值。原因在 information_schema_stats_expiry,默认 86400 秒(24 小时)。我们拿官方 mysql:8.4 镜像对了一下,上游默认值也是 86400,所以这是继承来的,不是 GreatSQL 改的。
第二层:就算 ANALYZE 完了,data_length 仍然小于磁盘上的真实占用。
同一张表,两个来源:
表tables.data_length(ANALYZE 后)innodb_tablespaces.file_size
probe_x(6000 行)212,992294,912
probe_orders(2000 行)65,536 + 数据页245,760
probe_lag(2000 行)98,304180,224
probe_customers(3 行)16,384131,072
差了 30%~45%。原因是 data_length 来自 mysql.innodb_table_stats 的聚簇索引页数估算,而表空间文件里还有回滚段、碎片和预分配。
所以想回答"这张表占多少磁盘",该读的是 information_schema.innodb_tablespaces.file_size,不是 tables.data_length。 我们自己以前就只读后者。
我们自己写错的地方得说清楚,上面不全是引擎的问题:
1. 我们在 SQL 里直接写 DATA_LENGTH + INDEX_LENGTH,没加 COALESCE。在 GreatSQL 和 MySQL 上没事,一到 StarRocks 就全变 NULL——不是它先报零,是我们把能读到的也弄没了。现在统一改成 DATA_LENGTH + COALESCE(INDEX_LENGTH, 0)。
2. 我们所有语句一律走 mysql2 的 execute()(二进制 prepared 协议),包括没参数的。SHOW、EXPLAIN 这类在不少兼容引擎的 prepared 协议里没实现,于是 SingleStore 挂了四个功能、StarRocks 挂了两个。改成没参数的走文本协议就全好了。
顺便记两条· SHOW ENGINES 里有一个 dlk(datalink storage engine),这是别处没见过的。
· performance_schema 里 5 张 replication_group_* 表在单机模式下就已经存在,做 MGR 监控面板的可以直接读。

如果各位在 GreatSQL 上跑出过和这些对不上的结果,很想听听。上面每条都标了版本号,换个版本结论可能就不一样了。
全部回复(8)
yejr 2026-9-24 16:03:35
欢迎新来的小伙伴
LibreDB 2026-9-24 17:05:22
谢谢。

我们是土耳其的一个小团队,在做一个开源的数据库 IDE,这次把 GreatSQL 接进来做兼容测试,顺手把踩到的东西写在上面那篇里了,包括我们自己写错的两处。

有一处想请教:帖子里提到的统计信息延迟,我们拿官方 mysql:8.4 镜像做了同样的对照,两边行为一致,所以判断这是 InnoDB 本身的采样机制,跟 GreatSQL 的改动无关。这个理解对吗?如果 GreatSQL 在这块做过调整,我们想把说明改准确。
reddey 2026-9-29 09:53:06
内容写得很好
一个学艺不精的国产数据库爱好者
LibreDB 2026-10-2 17:28:57
谢谢 @reddey 的认可。

上面那个统计信息延迟的问题还想再请教一下:我们拿官方 mysql:8.4 镜像做了同样的对照,两边行为一致,information_schema_stats_expiry 默认都是 86400,所以倾向认为是上游 MySQL 8.x 的统计信息缓存机制,跟 GreatSQL 的改动无关。GreatSQL 在这块有没有做过调整?如果有熟悉的朋友能帮忙确认一下,我们就把帖子里的说法改准确。
liurui 6 天前

内容写得很好
liurui 6 天前

欢迎新来的小伙伴
zjj 前天 12:03
感谢分享,这篇实测很有价值,尤其是“同一套探针跑 42 种数据库”这个对比方式,比单纯看文档有说服力得多。
你提到的几项兼容性点,确实都是 MySQL 协议兼容里容易踩坑的地方:version()、SHOW STATUS LIKE、information_schema.PROCESSLIST、performance_schema、information_schema.statistics、EXPLAIN FORMAT=JSON、KILL QUERY、外键约束、INDEX_LENGTH 这些,对 IDE、监控面板、健康检查、ER 图生成这类工具影响很大。
关于表大小那块,你的判断是对的:information_schema.TABLES 里的 DATA_LENGTH / INDEX_LENGTH / TABLE_ROWS 受 information_schema_stats_expiry 控制,默认 86400 秒,属于缓存统计值;而 InnoDB 表空间文件里还包含回滚段、碎片、预分配空间,所以 data_length 小于真实磁盘占用是正常现象。 如果工具需要更接近“真实磁盘占用”,读 innodb_tablespaces / INNODB_DATAFILES / FILES 这类表空间元数据会更合适。
顺便补充一点:GreatSQL 8.4.4-5 是基于 Percona Server for MySQL 8.4.4 系列构建的,所以这些统计行为、performance_schema、replication_group_* 表等,更多是继承自 MySQL/Percona 体系;GreatSQL 的增强主要在 MGR、复制、性能和安全侧。
最后两条也很有用:dlk 引擎和单机下就存在的 replication_group_* 表,对做 MGR 监控面板的同学确实有帮助。如果后面方便,建议把探针 SQL、对比表、复现步骤整理成一份 Gitee issue,哪怕不是 Bug,也能作为“兼容性实测报告”沉淀下来,后面其他做客户端、驱动、IDE 的人会很需要。
21159 昨天 11:04
写的很好
LibreDB

1

主题

0

博客

3

贡献

新手上路

Rank: 1

积分
6

合作电话:010-64087828

社区邮箱:greatsql@greatdb.com

社区公众号
社区小助手
QQ群
GMT+8, 2026-10-15 10:56 , Processed in 0.023786 second(s), 17 queries , Redis On.
快速回复 返回顶部 返回列表