首批通过分布式安全可靠测评,为关键业务系统打造
查询 OceanBase V1.4.x \~ V3.2.x 版本的索引状态
更新时间:2026-04-13 15:31:21
注意
- 此方法适用于 OceanBase V1.4.x \~ V3.2.x 版本,查询索引进度需要使用 sys 租户帐密。
- OceanBase V4.1 及之后的版本可以通过更加简单的方法查询索引进度,详情请参见 查询 OceanBase V4.x 版本的索引状态。
索引状态
索引创建的 SQL 层语义
作为分布式数据库,OceanBase 与传统关系数据库的索引创建过程区别如下:
使用 OceanBase V2.2 之前的版本创建索引时,会异步执行该 DDL 语句,即会直接将创建索引的 DDL 语句返回至 Client 端,由 Server 端异步执行索引创建任务。其中,使用 OceanBase V1.x 版本创建的索引会在合并中执行;使用 OceanBase 2.x 之后的版本创建的索引会立即执行。
使用 OceanBase V2.2 及之后的版本创建索引时,会同步执行该 DDL 语句,但同时引入了一个对 Client 端 query timeout 机制语义的破坏。OBServer 和 OBProxy 在处理索引变更 DDL 时,会将 ob_query_timeout 值隐式修改为 0,即不超时执行。如果 Client 端设置了 query timeout ,该设置会被忽略;如果 Client 端设置了 socket timeout,在索引创建耗时大于 socket timeout 场景下,Client 会因为 socket timeout 而主动关闭连接,但数据库服务端创建索引过程仍在进行。
所以本质上 OceanBase 索引创建过程仍然为异步执行,当需要判断索引创建状态时,用户可以通过内部表查询,本文档介绍如何查询 OceanBase MySQL 模式和 OceanBase Oracle 模式下的索引状态。
索引创建过程
索引创建过程包含如下四个阶段:
准备阶段:生成索引表的元数据信息,将索引表设置成只写状态;等待之前未在索引表中插入数据的事务结束,获取构建快照点。
构建阶段:基于获取的快照点扫描主表数据,并写入到索引表基线 SSTable 中,而增量事务产生的数据写入到 Memtable 中,最后完成基线补全,即将快照点后的 dml 同步到索引中。
拷贝阶段:单副本上构建索引完成后,会通过一致性算法同步到索引表多个副本上。
收尾阶段:进行数据校验,唯一索引还需要进行唯一性校验,校验完成后,将索引表设置成可读写状态,否则将其设置成不可用状态。
查询 索引状态
内部表 __all_table_v2 用于维护每个索引的元数据,其中 index_status 枚举值表示索引状态,不同的 OceanBase 版本对应的index_status索引状态不完全一致。具体如下表所示:
| index_status | OceanBase V1.4.7x 版本 | OceanBase V2.2.7x 之后的版本 |
|---|---|---|
| 1 |
|
索引创建中。 |
| 2 | 索引正常使用。 | 索引正常使用。 |
| 3 | 新建唯一索引后(唯一索引两次合并生效),处于第一次合并和第二次合并中间,唯一性校验过程中。 | 无此状态,使用 OceanBase V2.2 之后的版本创建索引后即时生效,不再需要发起合并生效。 |
| 5 | 如果索引出错,可通过drop语句删除索引后,执行create语句重新创建索引。 |
一般不会出现此状态,使用 OceanBase V2.2 之后的版本创建索引失败,会自动删除该索引。 |
MySQL 模式
在业务租户下查询索引状态。参考命令:
select t.table_name as table_name, t.table_id as table_id,
i.table_name as index_name, i.table_id as index_id,
case i.index_status
when 1 then 'UNAVAILABLE'
when 2 then 'AVAILABLE'
when 3 then 'UNIQUE_CHECK'
when 5 then 'ERROR'
else 'UNKNOWN'
end as index_status
from
oceanbase.__all_table_v2 t
join oceanbase.__all_table_v2 i on t.table_id = i.data_table_id
JOIN oceanbase.__all_database d on t.database_id = d.database_id
where
d.database_name = 'test'
and t.table_name = 't_test';
示例:

Oracle 模式
在业务租户下查询索引状态。参考命令:
SELECT T.TABLE_NAME AS TABLE_NAME,
I.TABLE_NAME AS INDEX_NAME,
CASE I.INDEX_STATUS
WHEN 1 THEN 'UNAVAILABLE'
WHEN 2 THEN 'AVAILABLE'
WHEN 3 THEN 'UNIQUE_CHECK'
WHEN 5 THEN 'ERROR'
ELSE 'UNKNOWN'
END AS INDEX_STATUS
FROM
SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T
JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT I ON T.TABLE_ID = I.DATA_TABLE_ID
JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON T.DATABASE_ID = D.DATABASE_ID
WHERE
D.DATABASE_NAME = 'your_user_name'
AND T.TABLE_NAME = 'your_table_name';
查询索引任务
用户可以通过虚表 __all_virtual_sys_task_status 查询索引创建任务是否存在。如果 __all_virtual_sys_task_status 中包含对应的任务,说明索引创建已在补数据阶段,补数据是索引创建过程最耗时的阶段。对于多分区场景,每个分区会在 __all_virtual_sys_task_status 中对应一条记录。
在业务租户下,查询__all_virtual_sys_task_status 中的索引创建任务。参考命令:
select start_time, task_type, svr_ip, comment
from __all_virtual_sys_task_status
where tenant_id=1014;
通过虚表 __all_virtual_sys_task_status 查询的索引任务状态:
能够查询到任务,说明索引创建过程执行正常,请耐心等待索引创建完成。
未查询到任务,说明索引创建过程失败,请检查 OBServer 日志分析失败原因。
- 索引创建中。
- 索引刚创建未生效,需要合并一次才会生效。
注意
Oceanbase V2.2 及之后的版本,如果__all_virtual_sys_task_status 中未查询到任务,但索引状态仍为 UNAVAILABLE,请联系 Oceanbase 技术支持进行分析和排查。
其中,可以在 comment 字段查看任务相关的信息,comment 字段值示例如下:
build index task: pkey={tid:1101710651081589, partition_id:0, part_cnt:0}
index_id=1101710651081594 snapshot_version=1686295718878029 parallelism=1
| 参数 | 说明 |
|---|---|
| tid | table_id。 |
| partition_id | 分区 ID。 |
| index_id | 索引的 table_id。 |
注意
sys 租户下内部表记录的 table_id 与业务租户下的 table_id 不同,同时会拼接 tenant_id 到高 32 位。