问题现象
生产环境中,执行特定 SQL 语句时,OceanBase 集群中存在不工作的 OBServer,具体表现为执行以下 SQL 语句时 OBServer 出现 core dump 现象:
OceanBase(admin@test)> EXPLAIN EXTENDED SELECT 1 FROM (SELECT c1 FROM t1 UNION ALL SELECT c1 FROM t1 ORDER BY c1+1);
+----------------------------------------------------------------------------------------------------------------------+
| Query Plan |
+----------------------------------------------------------------------------------------------------------------------+
| ================================================================ |
| |ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)| |
| ---------------------------------------------------------------- |
| |0 |SUBPLAN SCAN |ANONYMOUS_VIEW1|2 |8 | |
| |1 |└─SORT | |2 |8 | |
| |2 | └─UNION ALL | |2 |8 | |
| |3 | ├─TABLE FULL SCAN|t1 |1 |4 | |
| |4 | └─TABLE FULL SCAN|t1 |1 |4 | |
| ================================================================ |
| Outputs & filters: |
| ------------------------------------- |
| 0 - output([1]), filter(nil), rowset=16 |
| access(nil) |
| 1 - output([UNION([1])(0x7f8755412700)]), filter(nil), rowset=16 |
| sort_keys([UNION([1])(0x7f87554100d0) + 1(0x7f87554108b0), ASC]) |
| 2 - output([UNION([1])(0x7f87554100d0) + 1(0x7f87554108b0)], [UNION([1])(0x7f8755412700)]), filter(nil), rowset=16 |
| 3 - output([1]), filter(nil), rowset=16 |
| access(nil), partitions(p0) |
| is_index_back=false, is_global_index=false, |
| range_key([t1.__pk_increment(0x7f8755411ac0)]), range(MIN ; MAX)always true |
| 4 - output([1]), filter(nil), rowset=16 |
| access(nil), partitions(p0) |
| is_index_back=false, is_global_index=false, |
| range_key([t1.__pk_increment(0x7f8755411da0)]), range(MIN ; MAX)always true |
| Used Hint: |
| ------------------------------------- |
| /*+ |
| |
| */ |
| Qb name trace: |
| ------------------------------------- |
| stmt_id:0, stmt_type:T_EXPLAIN |
| stmt_id:1, SEL$1 |
| stmt_id:2, SET$1 > SET$0111ED85 |
| stmt_id:3, SEL$2 |
| stmt_id:4, SEL$3 |
| Outline Data: |
| ------------------------------------- |
| /*+ |
| BEGIN_OUTLINE_DATA |
| FULL(@"SEL$2" "test"."t1"@"SEL$2") |
| FULL(@"SEL$3" "test"."t1"@"SEL$3") |
| PROJECT_PRUNE(@"SET$1") |
| OPTIMIZER_FEATURES_ENABLE('') |
| END_OUTLINE_DATA |
| */ |
关键诊断信息
触发条件
SQL 语句中使用了
UNION ALL后跟ORDER BY语句,并且ORDER BY中的复合表达式引用了 UNION 列。ORDER BY表达式中包含了投影项的复合表达式。
事前巡检
检查 SQL 语句中是否存在
UNION ALL后跟ORDER BY的情况,特别是当ORDER BY中的表达式引用了 UNION 列时。审核 SQL 语句,确保
ORDER BY语句中的列有明确的归属。
事后诊断
查看 OBServer 的日志文件,确认是否有 core dump 的相关记录。
分析 core dump 堆栈,查找与
resolver阶段相关的异常信息,特别是涉及query transformation的部分。
问题原因
set query 的投影裁剪没有正确考虑 order expr,导致在 ORDER BY 语句中使用包含投影项的复合表达式时,OceanBase 内核在处理过程中出现了 BUG。
问题的风险及影响
SQL 执行时 OBServer core dump,可能导致系统停机。
SQL 结果正确性问题,可能影响业务数据的准确性。
影响租户
影响 OceanBase 数据库中的 SYS 租户和 Oracle 租户以及 MySQL 租户。
影响版本
OceanBase 数据库企业版 V4.2.1 GA(oceanbase-4.2.1.0-100000182023092722)及之后版本。
解决方法
应急方法: 在 SQL 语句中添加 Hint
/*+NO_QUERY_TRANSFORMATION*/来规避问题。彻底解决建议: 升级至问题已修复版本。目前已修复的版本包括 OceanBase 数据库企业版 V4.2.1 BP10 Hotfix5(oceanbase-4.2.1.10-110050012025011614)版本、V4.2.1 BP10 Hotfix6(oceanbase-4.2.1.10-110060022025022409)版本、V4.2.1 BP11(oceanbase-4.2.1.11-111000052025032520)及之后版本。
规避方式
避免在
UNION ALL后的ORDER BY语句中使用没有明确归属的复合表达式。在 SQL 语句中使用 Hint
/*+NO_QUERY_TRANSFORMATION*/来防止触发此 BUG。