首批通过分布式安全可靠测评,为关键业务系统打造
执行 UDF 报错 -4013
更新时间:2025-05-07 12:42
问题现象
当在一个 SQL 中多次执行 UDF 时,报错 -4013,报错信息如下。
客户端报错。
```shell ORA-00600: internal error code, arguments: -4013, No memory or reach tenant memory limit ```日志报错信息。
```shell WARN [PL] init (ob_pl.cpp:527) [100338][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=34] [dc=0] fail to exec ob_write_string( ctx.get_allocator(), session_info.get_current_query_string(), cur_query_)(ret=-4013) WARN [PL] execute (ob_pl.cpp:1361) [100338][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=4] [dc=0] fail to exec stack_ctx.init(*(ctx.get_my_session()), ctx, routine->is_autonomous(), routine->is_function() || in_function || (package_id != OB_INVALID_ID && ObTriggerInfo::is_trigger_package_id(package_id)))(ret=-4013) WARN [SQL.ENG] calc_resultN (ob_expr_udf.cpp:488) [100338][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=5] [dc=0] fail to exec pl_engine->execute(*(expr_ctx.exec_ctx_), *(expr_ctx.calc_buf_), package_id, udf_id_, subprogram_path_, *params, nocopy_params_, result, __null, false, true, loc_, is_called_in_sql())(ret=-4013, udf_id_=37, udf_package_id_=xxxxx, is_udt_udf_=false, result={"NULL":"NULL"}) WARN [SQL.ENG] eval (ob_expr_operator.cpp:536) [100338][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=8] [dc=0] calc result failed(ret=-4013, param_num_=-1, name_="user_define_function", get_type_name(type_)="T_FUN_UDF") WARN [SQL.ENG] eval (ob_infix_expression.cpp:488) [100338][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=7] [dc=0] expr evaluate failed(ret=-4013, type=661, type_name="T_FUN_UDF") WARN [SQL.ENG] calc (ob_infix_expression.cpp:306) [100338][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=6] [dc=0] expr evaluate failed(ret=-4013) WARN [SQL.ENG] calc_and_project (ob_sql_expression.cpp:380) [100338][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=4] [dc=0] calc expr result failed(ret=-4013) WARN [SQL.ENG] calculate_row_inner (ob_phy_operator.cpp:760) [100338][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=6] [dc=0] calculate column expression failed(ret=-4013 WARN [SQL.ENG] get_next_row (ob_phy_operator.cpp:515) [100338][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=27] [dc=0] calculate row failed(ret=-4013) WARN [SQL.ENG] get_next_row (ob_phy_operator.cpp:497) [100338][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=4] [dc=0] get next row failed(ret=-4013, type=10, op="PHY_SCALAR_AGGREGATE") WARN [SQL.EXE] get_next_row (ob_execute_result.cpp:141) [100338][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=5] [dc=0] get next row from operator failed(ret=-4013) ```
问题原因
目前已知的使用 ObExprOperatorCtx 的表达式包括 encode_sortkey、in、JOIN_BLOOM_FILTER、like、nlssort、date_format、random、subquery、regexp。
问题的风险及影响
SQL 执行报错,内存爆,影响其他 SQL,带来稳定性风险。
影响的版本
所有已发布的版本。
解决方法及规避方式
解决方法
在 UDF 函数的定义中使用 DETERMINISTIC 关键字。
```SQL
CREATEFUNCTION my_func(param1 INT, param2 VARCHAR(20))
RETURNSINT
DETERMINISTIC
BEGIN
-- UDF函数的实现逻辑
END;
```
规避方式
方式一:如果没有办法优化为
DETERMINISTIC,也可以分析 SQL 语句将 SQL 语句中的UDF调用进行聚合,比如多个相同的UDF调用可以仅调用一次等。方式二:避免使用带有
ObExprOperatorCtx的表达式。