---
title: 增量 schema 刷新报错 OB_EAGAIN（-4023）的原因和解决方法-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于增量 schema 刷新报错 OB_EAGAIN（-4023）的原因和解决方法相关的常见问题和使用技巧，帮助您快速解决增量 schema 刷新报错 OB_EAGAIN（-4023）的原因和解决方法的难题。
---
切换语言

- 简体中文
- English

划线反馈

# 增量 schema 刷新报错 OB_EAGAIN（-4023）的原因和解决方法

更新时间：2026-07-02 15:41

适用版本： V4.0.x、V4.1.x、V4.2.x、V4.3.x 内容类型：Troubleshoot  

## 问题现象

在 OceanBase 数据库 V4.x 版本环境下进行增量 Schema 刷新时，出现 OB_EAGAIN（错误码 -4023）错误而导致刷新失败。

## 关键诊断信息

在增量的 Schema 刷新时出现下面的日志和报错信息。

```shell
[2025-04-16 02:32:38.933683] ERROR [RS] refresh_schema (ob_ddl_service.cpp:28745) [3862302][DDLTransCtr][T0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=3][errcode=-5410]
Refresh schema failed continuously, ddl may be hung(msg="refresh schema failed", ret=-4023, ret="OB_EAGAIN", refresh_count=3)

```

![image01](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/tenant/20250711incremental-schema-refresh-error-ob-eagain-402308.png)

在排查时遇到刷新时的报错日志信息。

![image02](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/tenant/20250711incremental-schema-refresh-error-ob-eagain-402309.png)

## 问题原因

出现这种现象的原因可能与 Schema 槽位已经被全部占满了有关，以下将简要介绍 Schema 槽位的概念，并说明如何排查问题是否由槽位导致。

### 提前知识

Schema 信息按租户划分，每个租户包含多个版本。每个版本记录了该租户在特定时间点的所有 Schema 信息，这些信息由多种类型的 Schema 对象组成，如表对象、数据库对象等。

![image03](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/tenant/20250711incremental-schema-refresh-error-ob-eagain-402301.png)

### Schema 槽位

- 负责管理由 Schema 主动刷新生成的 Schema 信息，维护多个版本的 Schema 信息。
 - 具有固定数量的槽位（由租户级别配置项 `_max_schema_slot_num` 控制，默认为 128 个），只有当某个版本的 Schema 信息被放置到槽位中时，才对其他模块可见。
 - 负责管理各个版本 Schema 信息的引用计数，新生成的 Schema 信息将被放置在空槽位中，或替换 `schema_version` 最小的且未被引用的槽位。

### 错误码提示

当遇到错误码 `OB_EAGAIN（-4023）`时，可以考虑一下槽位已满的问题。

- 要判断 Schema 槽位是否已满，可以通过搜索日志中的 `schema_mgr_item` 来确认。

  ![image04](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/tenant/20250711incremental-schema-refresh-error-ob-eagain-402302.png)

  如果打印出来这样的日志的个数达到 `_max_schema_slot_num` 并且 `ref_cnt` 都不为 0，则表明槽位已经全部被占满了且无可淘汰槽位（具体哪个模块引用参考本文档 **附录** 这一节内容）。
 - 高版本可以查看表 `__all_virtual_schema_slot` 查看对应租户的 `slot_id` 的个数和引用计数，来查看槽位是否被放满且没有可以淘汰的槽位。

  ![image05](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/tenant/20250711incremental-schema-refresh-error-ob-eagain-402303.png)

### 槽位满

槽位满存在以下两种情况：

- 某些低版本的 Schema 信息被异常地持续引用，导致这些信息占用槽位且无法正常释放。由于这些 Schema 信息始终被引用，淘汰算法无法将其从槽位中移除，最终造成槽位被占满。
 - 频繁执行 DDL 操作，产生大量 Schema 信息占用槽位。这些 Schema 信息都是被正常引用的，因此也会导致 Schema 槽位被占满。

为了确定具体是哪种情况，可以用下面的 SQL 在系统租户下执行以下查询，监控当前引用至少落后 2h 以上 Schema 版本的情况，此时可能有大事务、长 query，引用计数泄漏或者指定版本取 guard 的情况。

```shell
select a.*, b.latest_schema_version from (select * from __all_virtual_schema_slot where total_ref_cnt > 0) as a join (select tenant_id, max(refreshed_schema_version) as latest_schema_version from __all_virtual_server_schema_info group by tenant_id) as b where a.tenant_id = b.tenant_id and ((b.latest_schema_version - a.schema_version) / 1000 / 1000) >= 2 * 3600;

```

![image06](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/tenant/20250711incremental-schema-refresh-error-ob-eagain-402304.png)

如果表里面的内容不为空，则表示有槽位被异常引用，可以通过 `ref_info` 来看引用的模块是哪个，去找相应的模块去询问（具体什么 Mod 去找哪个模块请参考本文档 **附录** 这一节内容）。如上图中信息显示 `CACHED_GUARD` 则表示有 session 持有 guard 导致槽位被异常占用。

对于SQL相关的模块，建议从以下几个方面进行排查：

1. 对于外部模块的 SQL，这可以通过查询 `__all_virtual_session_info` 和 `__all_virtual_processlist` 表来实现。

   ```shell
   select thread_id, time, state, svr_ip, svr_port, left(info,30), trace_id from __all_virtual_session_info where time > 1000 and id > 0 and state != 'SELLP' order by time desc;

   ```

   ![image07](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/tenant/20250711incremental-schema-refresh-error-ob-eagain-402305.png)

   过滤掉 `state` 为 `SLEEP` 的记录，查看 `time` 值较大的信息，这些通常是长时间持有引用的 SQL。可以联系对应模块的 OceanBase 数据库技术支持人员确认具体情况。

   ![image08](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/tenant/20250711incremental-schema-refresh-error-ob-eagain-402306.png)

   此外，还可以通过日志来检查 session 的状态。如果持续出现 `used_session_count` 不等于 `hold_session_count`，可能意味着存在 session 泄漏问题。具体含义如下：

      - **used_session_count：** 表示 session 分配器已分配的 session 数量。
      - **hold_session_count：** 表示 session mgr 中记录的 session 数量。

       当这两个值相等时，说明所有分配出去的 session 都在 session mgr 中被正常管理。

       ```shell
       $grep 'get current session count' observer.log.2022060611*
       observer.log.20220606110048:[2022-06-06 11:00:43.344867] INFO  [SQL] ob_sql_session_mgr.cpp:487 [366332][0][Y0-0000000000000000-0-0] [lt=6] get current session count(
       used_session_count=1825, hold_session_count=1825, session_leak_count_threshold=100)
       observer.log.20220606110203:[2022-06-06 11:01:58.651943] INFO  [SQL] ob_sql_session_mgr.cpp:487 [366332][0][Y0-0000000000000000-0-0] [lt=6] get current session count(
       used_session_count=1928, hold_session_count=1928, session_leak_count_threshold=100)

       ```
 2. 对于执行中的 `inner_sql` 长时间持有引用的情况，由于这些 `inner_sql` 不会出现在 `__all_virtual_session_info` 和 `__all_virtual_processlist` 表中，因此需要通过 obstack 检查是否有线程 hang 住的情况（使用 `obstack _thread_id`_生成堆栈信息，查看具体卡在哪个环节。同时，可以使用 `top -H` 命令检查线程的 CPU 占用率是否达到 100%，如果是，可能陷入了死循环）。以下是一些常见的长超时 `inner_sql` 情况：

      - 涉及 `inner_sql` 双写隐藏表或隐藏分区的离线 DDL 操作，可以通过查询 `__all_virtual_ddl_task_status` 表来查看是否有长时间运行的任务。
      - 查看日志中 `get_valid_duration_time` 相关的统计信息采集语句。

       ![image09](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/tenant/20250711incremental-schema-refresh-error-ob-eagain-402307.png)

   通过上面的方法来判定槽位满属于哪种情况，然后根据不同的情况去查看本文档 **解决方法** 这一节内容去解决。

## 问题的风险及影响

- 增量 Schema 刷新失败系统无法拿到最新的 Schema 信息，并且一直产生报错。
 - 因为无效内存占用导致 500 租户 Schema 内存占用大且无法释放。

## 适用版本

OceanBase 数据库 V4.x 版本。

## 解决方法

### 发生泄漏

发现有无效占用的存在，请联系相关模块的 OceanBase 数据库技术支持人员进行检查。

### 正常情况

如果未发现槽位被无效占用，可能是因为频繁的 DDL 操作导致生成了大量 Schema 信息。在这种情况下，可以通过扩展槽位来解决问题，具体操作是通过租户级配置项 `_max_schema_slot_num` 增大 Schema 槽位数（默认值为 128）。

```shell
ALTER SYSTEM SET _max_schema_slot_num=150 TENANT=<tenant_name>;

```

调大槽位时需要注意以下几点，并了解相关的风险：

- 槽位数最多可设置为 256，建议在调大槽位前减少 DDL 次数，以防止槽位再次被占满。
 - 调大槽位数可能会增加 Schema 模块占用的内存，需确保 OBServer 有足够的内存，以避免后续出现 `OOM`（Out of Memory）问题。
 - 若要调小槽位数，则需要重启 OBServer 才能生效。

## 规避方式

用户侧尽量减少频繁的做 DDL 的行为。

## 附录

下面为 `mod_ref_cnt` 中对应 MOD 和所负责的模块。

| mod_ref_cnt 中非 0 所在位置 | MOD | 负责的模块 |
| --- | --- | --- |
| 0 | MOD_STACK | rs |
| 1 | MOD_VTABLE_SCAN_PARAM | sql |
| 2 | MOD_INNER_SQL_RESULT | sql |
| 3 | MOD_LOAD_DATA_IMPL | 现在还未使用 |
| 4 | MOD_PX_TASK_PROCESSS | sql |
| 5 | MOD_REMOTE_EXE | sql |
| 6 | MOD_CACHED_GUARD | session 相关 |
| 7 | MOD_UNIQ_CHECK | 存储 DDL |
| 8 | MOD_SSTABLE_SPLIT_CTX | 现在还未使用 |
| 9 | MOD_RELATIVE_TABLE | 存储 |
| 10 | MOD_VIRTUAL_TABLE | rs |
| 11 | MOD_DAS_CTX | 现在还未使用 |
| 12 | MOD_SCHEMA_RECORDER | 存储 |
| 13 | MOD_SPI_RESULT_SET | sql |
| 14 | MOD_PL_PREPARE_RESULT | pl |
| 15 | MOD_PARTITION_BALANCE | rs |
| 16 | MOD_RS_MAJOR_CHECK | 存储 |

Previous

[OceanBase 数据库租户变量 explicit_defaults_for_timestamp 的使用说明](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000002854669)

Next

[Oracle 租户的 sys db 内，创建和已有内部表同名的表，会导致 schema 刷新异常](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000002762859) ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
