基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
列存表禁止创建向量索引
更新时间:2026-08-06 07:36
问题现象
在列存表上创建向量索引可能存在未经验证的潜在风险。已知的问题:在升级至 OceanBase 数据库 V4.3.5 BP5 版本之后,或者在该版本之后重启集群,在列存表上的向量索引查询会报错 4016。
关键诊断信息
升级到高版本/高版本重启后执行向量索引查询报错 4016。
4016 报错关键日志信息:
Unexpected lob locator。[2025-12-26 05:33:38.681807] WDIAG [STORAGE] init (ob_co_sstable_row_scanner.cpp:103) [3500490][T1002_L0_G0][T1002][xxxxxxxxxxxxxx-xxxxxxxxx 2D2185-0-0] [lt=0][errcode=-4016] Unexpected lob locator(ret=-4016, context.lob_locator_helper=NULL, param={table_id:855453, tablet_id:{id:2 32461}, ls_id:{id:1001}, cg_idx:0, read_info:{schema_column_count:54, schema_rowkey_cnt:15, rowkey_cnt:17, trans_col_index:-1, mview_old_new _col_index:-1, group_idx_col_index:-1, seq_read_column_count:15, max_col_index:36, is_oracle_mode:false, cols_index:{rowkey_mode:false, for_ memtable:false, array:{ObIArray:[cnt:16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36], data:0x7fe8db4c0740, count:16, allocator:0x7 fede5b60838, capacity:16, init_cnt:16}}, memtable_cols_index:{rowkey_mode:false, for_memtable:true, array:{ObIArray:[cnt:16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 34], data:0x7fe8db4c0790, count:16, allocator:0x7fede5b60838, capacity:16, init_cnt:16}}, cols_desc:{ObIA rray:[cnt:16, column_id=16 {type:"INT", collation:"binary", coercibility:"NUMERIC"} order=0, column_id=35 {type:"SMALLINT", collation:"binar y", coercibility:"NUMERIC"} order=0, column_id=17 {type:"DECIMAL UNSIGNED", collation:"binary", coercibility:"NUMERIC"} order=0, column_id=1 8{type:"VARCHAR", collation:"binary", coercibility:"INVALID"} order=0, column_id=19 {type:"TINYINT UNSIGNED", collation:"binary", coercibil ity:"NUMERIC"} order=0, column_id=20 {type:"MYSQL_DATE", collation:"binary", coercibility:"NUMERIC"} order=0, column_id=21 {type:"INT", coll ation:"binary", coercibility:"NUMERIC"} order=0, column_id=22 {type:"TINYINT", collation:"binary", coercibility:"NUMERIC"} order=0, column_i d=23 {type:"MEDIUMINT", collation:"binary", coercibility:"NUMERIC"} order=0, column_id=24 {type:"CHAR", collation:"dec8_swedish_ci", coercib ility:"INVALID"} order=0, column_id=25 {type:"DECIMAL INT", collation:"binary", coercibility:"unknown_collation_level"} order=0, column_id=2 6 {type:"INT", collation:"binary", coercibility:"NUMERIC"} order=0, column_id=27 {type:"VARCHAR", collation:"binary", coercibility:"INVALID" } order=0, column_id=30 {type:"TINYINT UNSIGNED", collation:"binary", coercibility:"NUMERIC"} order=0, column_id=32 {type:"BIGINT", collatio n:"binary", coercibility:"NUMERIC"} order=0, column_id=50 {type:"ARRAY", collation:"binary", coercibility:"EXPLICIT"} order=0], data:0x7fe8d b4c0670, count:16, allocator:0x7fede5b60838, capacity:16, init_cnt:16}, cg_idxs:{ObIArray:[cnt:16, 1, 20, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 , 15, 17, 35], data:0x7fe8db4c0870, count:16, allocator:0x7fede5b60838, capacity:16, init_cnt:16}, cols_extend:{ObIArray:[cnt:16, {pack:0, m in_max:0, sum:0, loose_min_max:0, bm25_token_freq_param:0, bm25_doc_len_param:0}, {pack:0, min_max:0, sum:0, loose_min_max:0, bm25_token_fre q_param:0, bm25_doc_len_param:0}, {pack:0, min_max:0, sum:0, loose_min_max:0, bm25_token_freq_param:0, bm25_doc_len_param:0}, {pack:0, min_m ax:0, sum:0, loose_min_max:0, bm25_token_freq_param:0, bm25_doc_len_param:0}, {pack:0, min_max:0, sum:0, loose_min_max:0, bm25_token_freq_pa ram:0, bm25_doc_len_param:0}, {pack:0, min_max:0, sum:0, loose_min_max:0, bm25_token_freq_param:0, bm25_doc_len_param:0}, {pack:0, min_max:0 , sum:0, loose_min_max:0, bm25_token_freq_param:0, bm25_doc_len_param:0}, {pack:0, min_max:0, sum:0, loose_min_max:0, bm25_token_freq_param:0 , bm25_doc_len_param:0}, {pack:0, min_max:0, sum:0, loose_min_max:0, bm25_token_freq_param:0, bm25_doc_len_param:0}, {pack:0, min_max:0, su m:0, loose_min_max:0, bm25_token_freq_param:0, bm25_doc_len_param:0}, {pack:0, min_max:0, sum:0, loose_min_max:0, bm25_token_freq_param:0, b m25_doc_len_param:0}, {pack:0, min_max:0, sum:0, loose_min_max:0, bm25_token_freq_param:0, bm25_doc_len_param:0}, {pack:0, min_max:0, sum:0, loose_min_max:0, bm25_token_freq_param:0, bm25_doc_len_param:0}, {pack:0, min_max:0, sum:0, loose_min_max:0, bm25_token_freq_param:0, bm25_ doc_len_param:0}, {pack:0, min_max:0, sum:0, loose_min_max:0, bm25_token_freq_param:0, bm25_doc_len_param:0}, {pack:0, min_max:0, sum:0, loo se_min_max:0, bm25_token_freq_param:0, bm25_doc_len_param:0}], data:0x7fe8db4c08c0, count:16, allocator:0x7fede5b60838, capacity:16, init_cn t:16}, has_all_column_group:false, need_truncate_filter:false, micro_block_format_version:1}, rowkey_read_info:{is_inited:true, compat_versi on:6, is_oracle_mode:false, is_cs_replica_compat:0, is_delete_insert_table:1, schema_column_count:37, schema_rowkey_cnt:15, rowkey_cnt:17, c ols_index:{rowkey_mode:true, for_memtable:false, schema_rowkey_cnt:15, column_cnt:39}, cols_desc:{ObIArray:[cnt:17, column_id=16 {type:"INT" , collation:"binary", coercibility:"NUMERIC"} order=0, column_id=35 {type:"SMALLINT", collation:"binary", coercibility:"NUMERIC"} order=0, c olumn_id=17 {type:"DECIMAL UNSIGNED", collation:"binary", coercibility:"NUMERIC"} order=0, column_id=18 {type:"VARCHAR", collation:"binary", coercibility:"INVALID"} order=0, column_id=19 {type:"TINYINT UNSIGNED", collation:"binary", coercibility:"NUMERIC"} order=0, column_id=20 {此日志来自 OceanBase 数据库存储层(ob_co_sstable_row_scanner.cpp),报错码 -4016 表示
Unexpected lob locator,通常与 LOB(大对象)定位器异常有关。
问题原因
自 OceanBase 数据库 V4.3.3 版本支持向量索引以来,向量索引相关特性从未在列存表上进行过完整验证。因此,在列存表上创建向量索引始终存在风险。虽然查询报错 4016 仅在升级到新版本之后才显现,但是即使在旧版本中,也不建议用户在列存表上创建向量索引,因为该行为本身即存在潜在风险。
问题的风险及影响
在 OceanBase 数据库 V4.3.5 BP5 及之后版本中,若在列存表上使用向量索引,重启后查询该索引将报错 4016。
对于旧版本,即使用户当前在列存表上创建并使用向量索引未遇到问题,仍存在未经验证的潜在风险,因此建议避免在列存表上使用向量索引。
适用版本
OceanBase 数据库 V4.3.5 BP5(oceanbase-4.3.5.5-105000212025111617)及之后版本。
解决方法
巡检手段
在升级前,先在系统 sys 租户下执行以下 SQL 查询是否存在已创建向量索引的列存表。
SELECT t.tenant_id, t.table_id, t.table_name, t.database_id
FROM oceanbase.__all_virtual_table t
INNER JOIN (
SELECT tenant_id, table_id
FROM oceanbase.__all_virtual_column_group
WHERE column_group_type NOT IN (0, 1)
GROUP BY tenant_id, table_id
) cg ON t.tenant_id = cg.tenant_id AND t.table_id = cg.table_id
INNER JOIN (
SELECT DISTINCT tenant_id, data_table_id
FROM oceanbase.__all_virtual_vector_index_info
) vi ON t.tenant_id = vi.tenant_id AND t.table_id = vi.data_table_id
WHERE t.table_type = 3
AND t.data_table_id = 0
AND t.column_store = 1;
若上述 SQL 查询存在此类表,则将主表修改为行存表可参考本文档 运维方法 章节内容。
运维方法
对于巡检sql查询的结果,需要执行一次offline DDL把主表改成行存表,具体方法如下:
运维方法一
通过
SHOW CREATE TABLE或SHOW INDEX记录向量索引的创建参数。删除表上的向量索引(如 OceanBase 数据库 V4.3.5 BP2 之前的版本,需要将全文索引和多值索引也一同 DROP 掉)。
执行以下 SQL 将主表改为行存表。
ALTER TABLE t_vec DROP COLUMN GROUP (each column);根据第一步记录的向量索引的创建参数,重新创建向量索引(如需要升级的话,这一步可延后到升级之后执行)。
注意
- 需要先删索引,在整个过程中无法使用索引。
- 执行 OFFLINE DDL 会阻塞 DML 写入以及其他 DDL 执行。
- OFFLINE DDL 会消耗一定的资源,建议在业务低峰期执行。
运维方法二(仅适用于 V4.3.5 BP2 及之后版本)
可直接使用 OFFLINE DDL 将主表转为非列存表。
ALTER TABLE t_vec DROP COLUMN GROUP (each column);
注意
上述 SQL 存在风险。
风险说明
风险一:快照长期持有不释放
当主表上存在两个或多个向量索引时,执行 OFFLINE DDL 会遇到快照被长期持有不释放导致卡合并的问题,建议谨慎使用。在执行 OFFLINE DDL 之后可通过以下 SQL 检查是否有 OFFLINE DDL 长期持有不释放的快照:
select *, scn_to_timestamp(snapshot_scn) from oceanbase.__all_acquired_snapshot where snapshot_type=1;注意
需要确保当前环境中没有正在执行的 DDL 任务,否则此 SQL 可能查询到其他 DDL 正常持有的快照。
确认是否有正在执行的 DDL 任务。
select * from oceanbase.__all_virtual_ddl_task_status\G;确保环境中没有正在执行的 DDL 任务之后,如果上述的第一条 SQL 查询到还有未释放的快照,基本可以确认是执行 OFFLINE DDL 时获取了快照并且无法正常释放。
风险二:Rebuild/Refresh 任务无法自动调度
在 OceanBase 数据库 V4.3.5 BP5 Hotfix6 以及 V4.4.1 Hotfix 11 之前的版本,存在执行 OFFLINE DDL 之后向量索引的 Refresh 任务和 Rebuild 任务无法被自动调度的问题。可以通过以下方法来确认并进行恢复:
执行以下查询
select gmt_create,gmt_modified,job,job_name,next_date,enabled, repeat_interval, exec_env from oceanbase.__all_tenant_scheduler_job where exec_env is null;若有查询有结果则说明存在向量索引的 Refresh 任务和 Rebuild 任务无法被自动调度的问题,需要通过系统 sys 租户登录进行后续步骤的恢复。若查询无结果则说明问题已经被修复,可以跳过后续步骤。
切换到目标用户租户。
ALTER SYSTEM CHANGE TENANT tenant_id=xxx;更新内部表。
UPDATE oceanbase.__all_tenant_scheduler_job SET exec_env='xxxxxxxxx' WHERE exec_env IS NULL AND job <> 0;其中
exec_env='xxxxxxxxx'可以从以下 SQL 查询结果中任选一个exec_env值进行替换,或填充为任意值,保证其不为空即可:SELECT gmt_create, gmt_modified, job, job_name, next_date, enabled, repeat_interval, exec_env FROM oceanbase.__all_tenant_scheduler_job WHERE exec_env IS NOT NULL;注意
- 执行 OFFLINE DDL 会阻塞 DML 写入以及其他 DDL 执行。
- OFFLINE DDL 会消耗一定的资源,建议在业务低峰期执行。
- 可能存在上述风险。
规避方式
目前新版本中在列存表上使用向量索引会导致查询报错的问题无法规避,只能通过上述 解决方法 章节中的 运维方法一 将主表改为行存表来解决,或在OceanBase 数据库版本升级之前,参考本文档进行巡查,提前排查并处理。