GreatSQL社区

搜索

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

49 2 前天 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 上跑出过和这些对不上的结果,很想听听。上面每条都标了版本号,换个版本结论可能就不一样了。
全部回复(2)
yejr 昨天 16:03
欢迎新来的小伙伴
LibreDB 昨天 17:05
谢谢。

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

有一处想请教:帖子里提到的统计信息延迟,我们拿官方 mysql:8.4 镜像做了同样的对照,两边行为一致,所以判断这是 InnoDB 本身的采样机制,跟 GreatSQL 的改动无关。这个理解对吗?如果 GreatSQL 在这块做过调整,我们想把说明改准确。
LibreDB

1

主题

0

博客

2

贡献

新手上路

Rank: 1

积分
4

合作电话:010-64087828

社区邮箱:greatsql@greatdb.com

社区公众号
社区小助手
QQ群
GMT+8, 2026-9-25 06:21 , Processed in 0.025583 second(s), 11 queries , Redis On.
快速回复 返回顶部 返回列表