在数据库运维中,SQL 执行报错非常常见而且可能对业务造成直接影响。 SQL 执行报错的原因有很多,比如没能正确连接到数据库、数据库用户权限不足、语法错误或数据不满足查询条件等等。
为了帮助大家快速定位问题根源并高效解决,这里总结了一套清晰、实用的 SQL 报错排查流程。这套流程提供明确的操作步骤,旨在提升问题处理效率,尽可能降低对业务的影响,为日常运维工作提供有力的支持。
下图是 SQL 执行报错问题排查流程图。
流程介绍
当遇到执行 SQL 报错的场景,可以按照该流程进行问题排查。
查看 SQL 报错信息,如果报错信息包含明确的错误码,请结合错误码信息进行问题排查;如果缺少明确的错误码,请判断错误类型:应用执行报错、手动执行 SQL 报错。
- 如果是应用执行报错,请参见应用异常问题排查。
- 如果是手动执行 SQL 报错,判断是否可以手动复现,不可复现,请参见其他场景问题排查;可复现,先复现问题场景。根据原场景,通过 2881 或 2883 端口连接 OB 集群,执行原 SQL 语句复现问题场景。
复现 SQL 报错场景后,按照如下步骤收集相关信息进行问题排查。
-
先获取 trace_id。
注意:必须执行完报错 SQL 后,第一时间执行以下语句;否则查出来的不是报错 SQL。- Oracle 租户,执行
select last_trace_id() from dual;
- MySQL 租户,执行
select last_trace_id;
- Oracle 租户,执行
-
获取实际执行 SQL 的主机信息。
OB 集群一般是多节点部署,可以通过如下 SQL 获取 SQL 实际执行的节点,然后再进行日志过滤。根据sql_audit
视图查询结果,svr_ip
对应的主机即实际执行该 SQL 主机。- V2.x 版本和 V3.x 版本,执行
select * from oceanbase.gv$sql_audit where trace_id='第二步获取的trace_id';
- V4.x 版本执行
select * from oceanbase.gv$ob_sql_audit where trace_id='第二步获取的trace_id';
- V2.x 版本和 V3.x 版本,执行
-
使用
ssh
命令登录到对应的主机。 -
使用 cd 命令进入对应的日志文件夹。
命令如下:cd /home/admin/oceanbase/log。 -
执行如下命令过滤日志中相关信息。
命令如下:grep “${trace_id}” observer.log observer.log.xxxx
根据日志提供的信息,结合错误码或相关错误提示信息等进行问题分析。更多日志信息,请参考日志概述;更多错误码信息,请参考 错误信息概述。如遇日志中信息不明确,可以联系技术支持人员一起排查。
以上为 SQL 执行报错问题排查流程,希望能为日常运维工作提供有力的支持。
典型案例
MySQL 模式
-
SQL 复现后,数据库回显有错误码信息
- 执行查询 JSON SQL,错误码
ERROR 5676 (HY000)
,请参见
- 执行查询 JSON SQL,错误码
执行查询 JSON SQL 报错 the interval is invalid。
-
当 SELECT 语句中包含较多的 OR 条件,或者大量 AND 连接的 IN 条件,或者大量的 AND NOT 条件时,执行 SELECT 报错
-4013,No memory or reach tenant memory limit
。请参见 SQL 解析阶段报错 -4013,租户内存满。 -
日志中有错误码信息
- 在可重复读的隔离级别下,业务执行过程中日志报错
ERROR 6235 (25000)
,请参见
- 在可重复读的隔离级别下,业务执行过程中日志报错
OceanBase 数据库执行 SQL 报错 Can’t serialize access for this transaction。
- OCP 监控平台告警报磁盘剩余空间不足
disk is almost full(ret=-4184)
,错误码4184
,请参见 SQL 查询导致磁盘空间不足报错 -4184。 - 执行 SQL 对一个
longtext
字段进行处理时报错ErrorCode=5098
,请参见
SQL 报错:Varchar value is too long for the column。
- 出现大量慢 SQL 重试的情况,且日志信息包含
errcode=-5307
,请参见 SQL 执行报错 errcode=-5307。 - 因 sql_work_area 不足导致 SQL 报错 -4013,请参见
因 sql_work_area 不足导致 SQL 报错 -4013 的原因和解决方法。
-
SQL 执行报错
error 4119 (RPC packet to send too long)
。通过trace_id
查询observer.log
可以看到信息obrpc packet payload execced its limit
,请参见 SQL 执行报错 -4119,RPC packet to send too long。 -
日志中有其他报错信息
- 应用端批量执行 SQL 语句时报错进行问题排查时,请参见 批量执行 SQL 报错。
- SQL 语句的过滤条件里,非同一个字段的判断条件超过 64 个时报错
-4002 Invalid argument
,请参见 SQL 语句过滤条件里存在非同一字段判断条件超过 64 个报错 -4002。
Oralce 模式
-
SQL 复现后,数据库回显有错误码信息
- 执行 update 向量形式的子查询时,使用
explain sql
命令解析语句时报错ORA-00600
,请参见 explain SQL 报错 4000。 - SQL 执行报错误代码
5001
,请参见 SQL 执行报错 unexpected STRING_VALUE ret=-5001。 - 对于一条含 c1,c2,c3 列的查询语句,如果列 c1,c2 命中索引,且 c1 或 c2 列上有多个 in 表达式,c1/c2/c3 任意组成一个向量表达式,那么在执行的时候就会报
internal error
,错误码ORA-00600
,请参见含多个 in 和向量表达式的 SQL 执行报错 4016。
- 执行 update 向量形式的子查询时,使用
-
SQL 有错误码,结合日志中错误码信息
- OceanBase 数据库 V3.x 版本中 Oracle 租户执行包含
regexp_replace
复杂表达式 SQL 报错ORA-00600
,请参见 OceanBase 数据库 V3.x 版本中 Oracle 租户执行包含 regexp_replace 复杂表达式时 SQL 报错 -4013 的原因和解决方法。 - 执行 SQL 报错 Timeout,错误码
ORA-00600
,请参见 SQL 执行报错 timeout。
- OceanBase 数据库 V3.x 版本中 Oracle 租户执行包含
-
日志中有其他报错信息
- 业务 SQL 子查询包含相同的列名,PS 执行报错
field list ambiguously defined
。请参见 业务 SQL 子查询包含相同的列名,PS 执行报错 field list ambiguously defined。
- 业务 SQL 子查询包含相同的列名,PS 执行报错