---
title: 数据的 collation type 不一致导致合并报 -4016-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于数据的 collation type 不一致导致合并报 -4016相关的常见问题和使用技巧，帮助您快速解决数据的 collation type 不一致导致合并报 -4016的难题。
---
切换语言

- 简体中文
- English

划线反馈

# 数据的 collation type 不一致导致合并报 -4016

更新时间：2026-06-15 09:16

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

## 问题现象

存储层合并报错 -4016，报错日志如下。

```sql
2023-08-07 10:30:34.150054] WARN  [COMMON] compare (ob_obj_compare.cpp:3500) [2310751][0][YB420ADC8116-000600FCCB4CC7D4-0-0] [lt=12] [dc=0] obj1 and obj2 can't compare(obj1={"VARCHAR":"9a58fd6331ac11eeba95f46b8c9686ed", collation:"utf8mb4_bin", coercibility:"IMPLICIT"}, obj2={"VARCHAR":"9a58fd6331ac11eeba95f46b8c9686ed", collation:"utf8mb4_general_ci", coercibility:"IMPLICIT"}, obj1.get_meta()={type:"VARCHAR", collation:"utf8mb4_bin", coercibility:"IMPLICIT"}, obj2.get_meta()={type:"VARCHAR", collation:"utf8mb4_general_ci", coercibility:"IMPLICIT"})

```

## 问题原因

PL 中 subquery 结果 `varchar` 类型的 collation 与期待值不一致时未做类型转换。

结果值作为表某一列的值插入到存储层，如果这一列是表的主键或索引列时，存储层在做数据合并时会报错 `-4016`。

## 问题的风险及影响

数据合并报错 `-4016`。

## 影响版本

OceanBase 数据库 V3.2.3 BP9（oceanbase-3.2.3.3-109000182023071410）、V3.2.4 BP5（oceanbase-3.2.4.5-105000012023081513）、V4.1.0 BP3（oceanbase-4.1.0.2-103000072023081111） 及之前的 BP 版本，V4.2.0 Beta 版本。

## 解决方法及规避方式

### 解决方法

- 先删除报错的索引，再进行数据合并。

  下面以一个示例说明。

  执行如下语句创建表 t1，包含了整型列 c1 和 varchar 列 uuid，其中 uuid 列有一个名为 `idx_hrmresource_uuid` 的索引。

  ```shell
  obclient> create table t1 (c1 int, uuid varchar(50) COLLATE utf8mb4_bin DEFAULT '0', KEY `idx_hrmresource_uuid` (`uuid`) BLOCK_SIZE 16384 LOCAL);

  ```

  执行如下语句，向表 t1 中插入一条数据。

  ```shell
  obclient> insert into t1 values (1, 'aaaa');

  ```

  执行如下语句创建了一个名为 `trg_t1` 的触发器（trigger），当在表 t1 中执行插入操作之前触发。

  ```shell
  DELIMITER //
  create trigger trg_t1 before insert on t1 for each row
  begin
  declare a int;
  set new.uuid = (select replace(uuid(), '-', ''));
  end;
  //
  DELIMITER ;

  ```

  插入一条数据发现 4016 报错。

  ```shell
  obclient> insert into t1 values (1, null);

  ```

  执行例子会直接报错 -4016，因为 `subquery` 表达式 (select replace(uuid()),'-','') 计算结果 `collation` 是`utf8mb4_general_ci`，`new.uuid` 的 `collation` 是 `utf8mb4_bin`，二者的 `collation` 不一致会导致存储层报错。

  执行如下语句 `DROP` 掉索引后再 `INSERT` 数据就不会报错了。

  ```shell
  obclient> alter table t1 drop key idx_hrmresource_uuid;

  ```
 - 升级到问题已修复版本。目前已修复的版本包含 V3.2.3 BP10（oceanbase-3.2.3.3-110000092023091219）、V3.2.4 BP6（oceanbase-3.2.4.6-106000062023110109）、V4.1.0 BP4（oceanbase-4.1.0.2-104000032023092119）、V4.2.0 GA（oceanbase-4.2.0.0-100010082023083014）及之后版本。

### 规避方式

在 PL subquery 表达式外面包一层 `cast` 函数，`cast` 到期待的 collation。

如上面的例子修改 trigger 定义如下。

```shell
create trigger trg_t1 before insert on t1 for each row
begin
declare a int;
set new.uuid = (select cast(replace(uuid(), '-', '') as char CHARACTER SET utf8mb4) COLLATE utf8mb4_bin);
end;
/

```

Previous

[minor merge 过程中丢列最终导致副本间 checksum error](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000443379)

Next

[卡合并，ob_micro_block_cache 模块报错：failed to allocate value, -4013](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000209919) ![有帮助](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) 咨询热线
