首批通过分布式安全可靠测评,为关键业务系统打造
select count(nullable 列) 查询正确性问题,结果偏多
更新时间:2026-05-26 09:46
问题现象
通过 DDL 在表尾部加多个列 (>=2) 后,select count(指定列) from table [where];其中指定列不是最后加的列,如果有转储数据,查询可能出现比预期多的结果。
关键诊断信息
触发条件
以下条件全部满足的场景:
最近(一般一天内,没有跨合并)通过 DDL 在表尾部加多个列 (>=2) 默认值为 null 。
存在转储 SSTable 数据,并且 SSTable 内新加列是 nop 值。
select count(指定列) from table [where]; 聚合下压到存储,并且其中指定列不是最后加的列。
事前巡检
无
事后诊断
explain select count(指定列) from table [where]; 可以查看到 count 有下压到存储(V4.x 版本开始默认下压)。
通过
sql_audit查看对应的记录blockscan相关统计项 >0 。通过
table_id查询__all_virtual_ddl_operation查看最近有多次加列,默认值为 null,并且 count 非最后 1 列。通过
tablet_id查询__all_virtual_table_mgr查看存在 size>0 增量 SSTable,通过 dump 增量 SSTable 中的宏块查看新加列是否为nop。
问题原因
在 MemTable 已有数据情况下,alter table 加多列比如 c1,c2,默认值为 null,再新写入数据,发生转储,此时转储 SSTable 中前面数据 c1,c2 列为 nop,select count (c1) 查询因为不是尾列,会走到存储下压 blockscan 逻辑,但此时从转储读出 nop 值直接用于判断是否为 null,导致被认为非 null 被统计。
问题的风险及影响
count 正确性问题。
影响租户
影响 OceanBase 数据库中的 SYS 租户和 Oracle 租户以及 MySQL 租户。
影响版本
OceanBase 数据库企业版 V4.1.0 GA(oceanbase-4.1.0.0-100001122023040322)及之后版本、V4.2.0 GA(oceanbase-4.2.0.0-100010082023083014)及之后版本、V4.2.1 GA(oceanbase-4.2.1.0-100000182023092722)及之后版本、V4.2.2 GA(oceanbase-4.2.2.0-100000082024011317)及之后版本、V4.3.0(oceanbase-4.3.0.0-100000072024020200)及之后版本。
解决方法及规避方式
解决方法:
升级至问题已修复版本。目前已修复的版本包括 OceanBase 数据库 V4.2.1 BP7(oceanbase-4.2.1.7-107000112024052920)及之后版本、V4.2.4(oceanbase-4.2.4.0-100000252024070621)及之后版本、V4.3.1(oceanbase-4.3.1.0-100000212024051522)及之后版本。
通过租户级配置项关闭聚合下压,命令如下。
alter system set _pushdown_storage_level=2;
规避方式:
无。