OceanBase 1.4.x ~ 3.2.x 索引状态查看

2024年 5月 7日 35.7k 0

本文适用于 OceanBase 1.4.x~3.2.x 版本索引状态查看。

OceanBase 4.1 开始可以通过更加简单的方式查看,参见另一篇博客 OceanBase 4.x 索引进度查看 。

索引创建的 SQL 层语义

作为分布式数据库,OceanBase 的索引创建过程和传统的关系数据库存在一些差别。

在 OceanBase 2.2 之前 版本,索引创建 DDL 语句是异步执行的,也就是说 DDL 语句执行会直接返回给 Client 端,由 Server 端异步执行索引创建任务。其中 OceanBase 1.x 版本中,索引构建是在合并中执行的,从 OceanBase 2.x 开始,索引构建改为立即执行。

从 OceanBase 2.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 模式和 Oracle 模式下索引状态查看的方法。

索引创建过程概述

索引创建过程简单来说包含如下四个阶段:

  1. 准备阶段:生成索引表的元数据信息,索引表设置成只写状态;等待之前未往索引表插入过数据的事务结束,获取构建快照点。
  2. 构建阶段:基于获取的快照点扫描主表数据,并写入到索引表基线SSTable中,而增量事务产生的数据写入到Memtable中,最后完成基线补全也就是将快照点后的dml同步到索引中。
  3. 拷贝阶段:索引构建是单副本上完成的,构建完成后会通过一致性算法同步到索引表多个副本上。
  4. 收尾阶段:进行数据校验,对于唯一索引还需要进行唯一性校验,一切完成后索引表设置成可读写状态,否则设置成不可用状态。

索引状态查看

内部表 __all_table_v2 维护了每个索引的元数据,其中 index_status 枚举值表示索引状态,其含义在不同 OB 版本概念并不完全一致,下表是 index_status 状态的解释。

index_status OB 1.4.7x 含义 OB 2.2.x + 含义
1 索引创建中;或者索引已经创建尚未生效,需要合并一次才会生效 索引创建中
2 索引正常使用 索引正常使用
3 唯一索引新建后(唯一索引两次合并生效),处于第一次合并和第二次合并中间,唯一性校验过程中 无此状态,OB 2.2 之后,索引创建之后即时生效,不再需要发起合并生效
5 索引出错,可通过重建索引解决,重建索引即 drop 再 create 一般不会出现此状态,OB 2.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';

样例如下

OceanBase 1.4.x ~ 3.2.x 索引状态查看-1

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';

索引任务查看

此方法适用于 OceanBase 2.x ~ 3.2.x ,查看索引进度需要使用 sys 租户帐密。

OceanBase 1.4 的索引构建是在合并中做的,所以可能无法索引创建命令发出之后就可以查看到索引任务。

您可以通过虚表 __all_virtual_sys_task_status 查看索引创建任务是否存在。能够从 __all_virtual_sys_task_status 查看到对应的任务,说明索引创建已经在补数据阶段,补数据是索引创建过程最耗时的阶段。对于多分区场景,每个分区在 __all_virtual_sys_task_status 有一条记录。

__all_virtual_sys_task_status 查询索引创建任务样例(在 sys 租户下查询):

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 2.2 及以后版本,如果__all_virtual_sys_task_status 中没有记录,但索引状态还是UNAVAILABLE,请联系技术支持介入分析排查。

其中任务相关的信息维护在 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 位。

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论