SQL 过长导致 FE 报错 java.lang.StackOverflowError: null

为了更快的定位您的问题,请提供以下信息,谢谢
【详述】执行了一个长度为 650k 左右的 SQL 主要条件组合如下:

SELECT  *  from xxx  WHERE ((collection_time >= '2024-06-27 23:55:32' AND collection_time >= '2024-06-28 00:05:32' AND geo_id in (613345344754810879,613345344752713727,613345344744325119,613345344746422271,613345344656244735,613345344717062143,613345344714964991,613345316611031039,613345316615225343,613345344756908031,613345344748519423,613345344750616575,613345344685604863,613345344647856127,613345344643661823,613345344652050431,613345344712867839,613345344710770687,613345344723353599)) OR (...)

所有的条件都是 AND 后再通过 OR 组合起来,SQL 总长度为:650k 左右。
【背景】
【业务影响】执行的时候卡住一会,然后 SQL 界面返回报错:
ERROR 1064 (HY000): Unknown error
查看 FE 日志主要报错:

java.lang.StackOverflowError: null
        at org.antlr.v4.runtime.CommonTokenStream.LB(CommonTokenStream.java:82) ~[antlr4-runtime-4.9.2.jar:4.9.2]
        at org.antlr.v4.runtime.CommonTokenStream.LT(CommonTokenStream.java:94) ~[antlr4-runtime-4.9.2.jar:4.9.2]
        at org.antlr.v4.runtime.Parser.unrollRecursionContexts(Parser.java:716) ~[antlr4-runtime-4.9.2.jar:4.9.2]
        at com.starrocks.sql.parser.StarRocksParser.expression(StarRocksParser.java:39443) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.primaryExpression(StarRocksParser.java:41088) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.valueExpression(StarRocksParser.java:40212) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.predicate(StarRocksParser.java:39767) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.booleanExpression(StarRocksParser.java:39641) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.expression(StarRocksParser.java:39355) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.primaryExpression(StarRocksParser.java:41088) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.valueExpression(StarRocksParser.java:40212) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.predicate(StarRocksParser.java:39767) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.booleanExpression(StarRocksParser.java:39641) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.expression(StarRocksParser.java:39355) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.primaryExpression(StarRocksParser.java:41088) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.valueExpression(StarRocksParser.java:40212) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.predicate(StarRocksParser.java:39767) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.booleanExpression(StarRocksParser.java:39641) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.expression(StarRocksParser.java:39355) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.primaryExpression(StarRocksParser.java:41088) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.valueExpression(StarRocksParser.java:40212) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.predicate(StarRocksParser.java:39767) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.booleanExpression(StarRocksParser.java:39641) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.expression(StarRocksParser.java:39355) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.primaryExpression(StarRocksParser.java:41088) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.valueExpression(StarRocksParser.java:40212) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.predicate(StarRocksParser.java:39767) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.booleanExpression(StarRocksParser.java:39641) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.expression(StarRocksParser.java:39355) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.primaryExpression(StarRocksParser.java:41088) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.valueExpression(StarRocksParser.java:40212) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.predicate(StarRocksParser.java:39767) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.booleanExpression(StarRocksParser.java:39641) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.expression(StarRocksParser.java:39355) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.primaryExpression(StarRocksParser.java:41088) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.valueExpression(StarRocksParser.java:40212) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.predicate(StarRocksParser.java:39767) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.booleanExpression(StarRocksParser.java:39641) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.expression(StarRocksParser.java:39355) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.primaryExpression(StarRocksParser.java:41088) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.valueExpression(StarRocksParser.java:40212) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.predicate(StarRocksParser.java:39767) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.booleanExpression(StarRocksParser.java:39641) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.expression(StarRocksParser.java:39355) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.primaryExpression(StarRocksParser.java:41088) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.valueExpression(StarRocksParser.java:40212) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.predicate(StarRocksParser.java:39767) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.booleanExpression(StarRocksParser.java:39641) ~[starrocks-fe.jar:?]
        at com.starrocks.sql.parser.StarRocksParser.expression(StarRocksParser.java:39355) ~[starrocks-fe.jar:?]

输出的内容都是循环的,非常长,所以就不都粘出来了。
【是否存算分离】否
【StarRocks版本】main-c273bd7
【集群规模】3fe(1 follower+2observer)+3be(fe与be混部)
【机器信息】CPU虚拟核/内存/网卡为:16C/128G/万兆
【联系方式】monchickey#gmail.com
【附件】无

admin set frontend config (“expr_children_limit” = “1000000”);
set parse_tokens_limit = 35000000 可以调整下这两个参数下试下,或者可以尝试将查询创建成视图然后查询。

您好,调整完参数后查询仍然报相同的错误。

StarRocks > ADMIN SHOW FRONTEND CONFIG LIKE "expr_children_limit";
+---------------------+------------+---------+------+-----------+---------+
| Key                 | AliasNames | Value   | Type | IsMutable | Comment |
+---------------------+------------+---------+------+-----------+---------+
| expr_children_limit | []         | 1000000 | int  | true      |         |
+---------------------+------------+---------+------+-----------+---------+
1 row in set (0.004 sec)

StarRocks > SHOW VARIABLES LIKE '%parse_tokens_limit%';
+--------------------+----------+
| Variable_name      | Value    |
+--------------------+----------+
| parse_tokens_limit | 35000000 |
+--------------------+----------+
1 row in set (0.005 sec)

StarRocks > 

然后尝试使用视图查询,但是创建视图时会出现报错:

ERROR 1064 (HY000): Unexpected exception: null

但是缩短 SQL 条件之后可以正常创建成功。

辛苦发下fe.log,连接哪个fe执行的发下哪个fe就可以,这个可能需要语法分析算法不太好解决

您好,这部分日志已经导出来了 fe.log.zip (19.2 KB)

一样出现该问题

sql在存算一体下执行有该错误,在存算分离下无问题,请问两者解析有差别吗

哥们,试试加大fe机器cpu和内存。

内存够,128G 呢

调大jvm配置

开始 FE JVM 设置的 8GB,执行 SQL 后看内存的使用情况,大约涨到 5G 多的时候就会报错。后来把 JVM 设置了 32GB,然后内存涨到了 10G 左右仍然会出现报错,但是报错信息和之前不同。
错误日志参考:fe.log (131.1 KB)

尝试调整JVM参数 -Xss set java thread stack size

-Xss2m

可以了,先调整了栈大小为 8m,默认是 1m,不过堆默认 8g 不够,也需要调大。
-Xss8m -Xmx32g
查询的时候会出现报错:

StarRocks planner use long time 3000 ms in logical phase, This probably because 1. FE Full GC, 2. Hive external table fetch metadata took a long time, 3. The SQL is very complex. You could 1. adjust FE JVM config, 2. try query again, 3. enlarge new_planner_optimize_timeout session variable

因为 SQL 解析优化时间过长出现的,然后调大 new_planner_optimize_timeout 参数:

-- 默认 3s
show variables like "new_planner_optimize_timeout";
set new_planner_optimize_timeout=300000;

调大后再查询就正常了,但是优化 SQL 为什么需要这么长时间呢,是因为条件太多吗?

是的OR太多,这块当前parser还没针对性的优化下。

你用的是哪个版本测试的?

main-c273bd7,是 6 月初拉的 main 分支最新的代码编译的