执行一个SELECT查询语句,还没到查询超时时间,就立即报错

【 使用环境 】测试环境
【 OB or 其他组件 】
【 使用版本 】OceanBase_CE_4.3.5.1
【问题描述】

如图所示,我们设置的查询超时时间是 60s。
但是在 Navicat 中对某些表执行任意查询操作,比如:

SELECT * FROM yl_channel LIMIT 1;

都会立即响应如下报错:

4012 - Timeout, query has reached the maximum query timeout: 60000000(us), maybe you can adjust the session variable ob_query_timeout or query_timeout hint, and try again.

请问这个问题要如何解决 ?

已知情况如下:

  1. 只有部分数据表会出现此情况,在这些表上执行任何查询都会报错。有另外一部分表上查询又没有这个问题。
  2. 不是等到设置的 60s 超时时间才报错,而是一执行SQL就立即报错。

@论坛小助手

根据您提供的信息,问题的核心是:在某些表上执行查询时,尽管设置了 60 秒的超时时间,但 SQL 查询会立即报错 4012 - Timeout。以下是可能的原因及解决方法:


1. 问题分析

已知条件:

  • 部分表存在此问题,而其他表正常。
  • 报错信息显示查询达到了最大超时时间 60000000(us)(即 60 秒),但实际上查询并未运行到 60 秒就立即报错。

可能原因:

根据文档片段和您的描述,以下几种情况可能导致此问题:

  1. 表或分区不可用

    • 如果目标表的部分分区或数据副本不可用,OceanBase 数据库可能会立即返回超时错误。
    • 这种情况下,即使设置了较大的超时时间,查询也无法继续执行。
  2. 租户资源限制

    • 如果租户的资源(如内存、CPU)不足,或者租户的配置参数(如 ob_query_timeout)被动态调整为较小值,可能会导致查询立即失败。
  3. 表元数据异常

    • 表的元数据可能存在异常,例如表的分区定义不正确或索引损坏,这会导致查询计划无法生成,从而触发超时错误。
  4. 网络或 OBProxy 配置问题

    • 如果使用了 OBProxy,可能是 OBProxy 的超时时间设置过短,导致查询在到达 OceanBase 数据库之前就被中断。
  5. Hint 或 Session 参数冲突

    • 如果查询中使用了 query_timeout Hint 或者会话级别的 ob_query_timeout 被动态修改为较小值,也可能导致查询立即失败。

2. 解决方法

方法一:检查表和分区状态

  • 使用以下 SQL 检查表及其分区的状态:
    -- 查看表的分区信息
    SELECT * FROM oceanbase.__all_virtual_partition WHERE table_id = (SELECT table_id FROM oceanbase.__all_table WHERE table_name = 'yl_channel');
    
    -- 查看表的副本分布
    SELECT * FROM oceanbase.__all_virtual_clog_stat WHERE tenant_id = (SELECT tenant_id FROM oceanbase.__all_tenant WHERE tenant_name = '<your_tenant_name>') AND partition_key IN (SELECT partition_key FROM oceanbase.__all_virtual_partition WHERE table_id = (SELECT table_id FROM oceanbase.__all_table WHERE table_name = 'yl_channel'));
    
  • 如果发现某些分区的副本不可用或状态异常,请尝试修复分区或重新加载数据。

方法二:检查租户资源和参数配置

  • 确认租户的 ob_query_timeout 参数是否被动态修改为较小值:
    SHOW VARIABLES LIKE 'ob_query_timeout';
    
  • 如果需要调整全局或会话级别的超时时间,可以执行以下命令:
    -- 修改租户级别的超时时间(单位:微秒)
    SET GLOBAL ob_query_timeout = 60000000;
    
    -- 修改会话级别的超时时间
    SET SESSION ob_query_timeout = 60000000;
    

方法三:检查表元数据

  • 如果怀疑表的元数据存在问题,可以尝试重建表或索引:
    ALTER TABLE yl_channel REBUILD PARTITION;
    ALTER TABLE yl_channel REBUILD INDEX;
    

方法四:检查 OBProxy 配置

  • 如果使用了 OBProxy,请确认其超时时间是否过短:
    • 默认情况下,OBProxy 的超时时间为 60 秒。如果需要调整,可以在 OBProxy 配置文件中修改 proxy_query_timeout 参数。
    • 示例配置:
      proxy_query_timeout: 60000000
      

方法五:排查 Hint 或动态参数冲突

  • 检查查询中是否使用了 query_timeout Hint:

    SELECT /*+ query_timeout(10000) */ * FROM yl_channel LIMIT 1;
    

    如果确实使用了 Hint,请确保其值与预期一致。

  • 检查是否存在动态修改会话参数的操作:

    SELECT * FROM oceanbase.__all_session_variable WHERE name = 'ob_query_timeout' AND value < 60000000;
    

3. 进一步排查建议

如果以上方法仍无法解决问题,建议按照以下步骤进一步排查:

  1. 收集诊断信息

    • 使用 OCP 或 obdiag 工具收集系统日志和性能指标。
    • 检查是否有相关告警或异常事件。
  2. 联系技术支持

    • 如果问题持续存在,请将以下信息提供给 OceanBase 技术支持团队:
      • 报错的具体场景和表结构。
      • 租户和集群的配置参数。
      • 相关的日志文件。

4. 总结

根据文档库中的信息(参考片段标题:4000 ~ 4499 -> ERROR 4012 (HY000) : Timeout阅读和管理 OceanBase 数据库 SQL 执行计划 -> 通过 Hint 生成指定计划 -> 常用 Hint -> QUERY_TIMEOUT Hint),问题可能由表或分区不可用、租户资源限制、表元数据异常、OBProxy 配置问题或 Hint/参数冲突引起。请按照上述方法逐一排查并解决问题。

详情请参考:

  1. 4000 ~ 4499
  2. 阅读和管理 OceanBase 数据库 SQL 执行计划
  3. 4500 ~ 4999

查一下这个变量设置的时间
SHOW VARIABLES LIKE ‘ob_query_timeout’;

配置无误,就是 60s 的设置。
不过后来过了一段时间,它自动恢复正常了,不知道是不是测试环境某个副本出现了短暂故障,所以所有以此作为主副本的数据表都会出现同样的问题。

感谢各位的热心回复。

正常情况下 不会有问题 建议出问题了 全部节点上observer.log日志发一下 如果是通过obproxy 连接的话建议obproxy.log obproxy_diagnosis.log 日志 也发一下 没有日志不好排查