admin管理员组

文章数量:1033364

OceanBase 字段扩容避坑:字符集变更导致 DDL 失败

作者:吕虎桥,爱可生 DBA 团队成员,主要负责 DMP 平台和 MySQL 数据库的日常运维及故障处理。

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文约 1100 字,预计阅读需要 3 分钟。

1. 背景

程序报错提示长度超过列长,需要扩容字段长度。在执行修改的时候报错 ERROR 1235 (0A000): Alter charset or collation type not supported,提示不支持字符集或排序规则变更。

数据库版本:OceanBase 3.2.3.0

2. 复现步骤

2.1 新建表

代码语言:javascript代码运行次数:0运行复制
create table user_info (
idbigintnotnull auto_increment primary keyCOMMENT'自增主键',
user_name varchar(30) CHARACTERSET utf8mb4 COLLATE utf8mb4_bin DEFAULTNULLCOMMENT'用户名',
address varchar(200) COMMENT'地址',
create_time datetime defaultcurrent_timestampCOMMENT'创建时间',
update_time datetime defaultcurrent_timestamponupdatecurrent_timestampCOMMENT'更新时间'
)defaultcharset utf8mb4;

2.2 修改表结构

代码语言:javascript代码运行次数:0运行复制
MySQL [mydb]> alter table user_info modify user_name varchar(50);
ERROR 1235 (0A000): Alter charset or collation type not supported

3. 问题分析

3.1 查看 MySQL 租户默认的字符集和排序规则

代码语言:javascript代码运行次数:0运行复制
MySQL [mydb]> show variableslike'%character%';
+--------------------------+---------+
| Variable_name            | Value   |
+--------------------------+---------+
| character_set_client     | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database   | utf8mb4 |
| character_set_filesystem | binary  |
| character_set_results    | utf8mb4 |
| character_set_server     | utf8mb4 |
| character_set_system     | utf8mb4 |
+--------------------------+---------+
7 rows in set (0.003 sec)

MySQL [mydb]> showvariableslike'%collation%';
+----------------------+--------------------+
| Variable_name        | Value              |
+----------------------+--------------------+
| collation_connection | utf8mb4_general_ci |
| collation_database   | utf8mb4_general_ci |
| collation_server     | utf8mb4_general_ci |
+----------------------+--------------------+

3.2 查看表和字段默认字符集、排序规则

代码语言:javascript代码运行次数:0运行复制
--查看表的默认字符集、排序规则
SELECT TABLE_NAME, CCSA.character_set_name AScharset, CCSA.collation_name AScollation
FROM INFORMATION_SCHEMA.TABLES T
    JOIN INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY CCSA
    ON T.table_collation = CCSA.collation_name
WHERE T.table_name = 'user_info';

+------------+---------+--------------------+
| TABLE_NAME | charset | collation          |
+------------+---------+--------------------+
| user_info  | utf8mb4 | utf8mb4_general_ci |
+------------+---------+--------------------+

--查看列默认字符集、排序规则
SELECT COLUMN_NAME, CHARACTER_SET_NAME AScharset, COLLATION_NAME AScollation
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'user_info'AND TABLE_SCHEMA = 'mydb';

+-------------+---------+--------------------+
| COLUMN_NAME | charset | collation          |
+-------------+---------+--------------------+
| id          | binary  | binary             |
| user_name   | utf8mb4 | utf8mb4_bin        |
| address     | utf8mb4 | utf8mb4_general_ci |
| create_time | binary  | binary             |
| update_time | binary  | binary             |
+-------------+---------+--------------------+

3.3 问题原因

在字段扩容的时候,没有声明列的排序规则,会自动继承表的排序规则 --> utf8mb4_general_ci,需要把列排序规则从 utf8mb4_bin 转换为 utf8mb4_general_ci,但是 OceanBase 3.2.3 不支持在线修改表的字符集、排序规则,更多参考[1]

3.4 解决方法

修改列的时候声明列的字符集、排序规则。

代码语言:javascript代码运行次数:0运行复制
MySQL [mydb]> alter table user_info modify user_name varchar(50) CHARACTERSET utf8mb4 COLLATE utf8mb4_bin DEFAULTNULLCOMMENT'用户名' ;
Query OK, 0 rows affected (0.050 sec)

MySQL [mydb]> showcreatetable user_info\G
*************************** 1.row ***************************
       Table: user_info
CreateTable: CREATETABLE`user_info` (
`id`bigint(20) NOTNULL AUTO_INCREMENT COMMENT'自增主键',
`user_name`varchar(50) CHARACTERSET utf8mb4 COLLATE utf8mb4_bin DEFAULTNULLCOMMENT'用户名',
`address`varchar(200) DEFAULTNULLCOMMENT'地址',
`create_time` datetime DEFAULTCURRENT_TIMESTAMPCOMMENT'创建时间',
`update_time` datetime DEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMPCOMMENT'更新时间',
  PRIMARY KEY (`id`)
) AUTO_INCREMENT = 1DEFAULTCHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0
1rowinset (0.009 sec)

4. 在 OceanBase 4.2.1 版本验证

代码语言:javascript代码运行次数:0运行复制
--查看数据库版本
MySQL [mydb]> select @@version;
+---------------------------+
| @@version                 |
+---------------------------+
| 5.7.25-OceanBase-v4.2.1.4 |
+---------------------------+

--修改列长度
MySQL [mydb]> alter table user_info modify user_name varchar(50) ;
Query OK, 0 rows affected (1.706 sec)

在 OceanBase 4.2.1 版本,字段长度扩容成功,列排序规则发生了变更,从 utf8mb4_bin 变更为 utf8mb4_general_ci

代码语言:javascript代码运行次数:0运行复制
SELECT COLUMN_NAME, CHARACTER_SET_NAME AScharset, COLLATION_NAME AScollation
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'user_info'AND TABLE_SCHEMA = 'mydb';

+-------------+---------+--------------------+
| COLUMN_NAME | charset | collation          |
+-------------+---------+--------------------+
| id          | NULL    | NULL               |
| user_name   | utf8mb4 | utf8mb4_general_ci |
| address     | utf8mb4 | utf8mb4_general_ci |
| create_time | NULL    | NULL               |
| update_time | NULL    | NULL               |
+-------------+---------+--------------------+

查看 OceanBase 官网,在 OceanBase 4.2.1 版本中列字段扩容属于 Online DDL[2],可以直接变更。但是这样就产生了一个潜在的风险,列排序规则变更为 utf8mb4_general_ci 会忽略大小写,可能会影响数据的一致性。

代码语言:javascript代码运行次数:0运行复制
MySQL [mydb]> insert into user_info (user_name,address) values ('Alice','上海');
Query OK, 1 row affected (0.051 sec)

MySQL [mydb]> insert into user_info (user_name,address) values ('alice','上海');
Query OK, 1 row affected (0.027 sec)

MySQL [mydb]> select * from user_info where user_name='alice';
+----+-----------+---------+---------------------+---------------------+
| id | user_name | address | create_time         | update_time         |
+----+-----------+---------+---------------------+---------------------+
|  1 | Alice     | 上海    | 2025-03-18 14:17:25 | 2025-03-18 14:17:25 |
|  2 | alice     | 上海    | 2025-03-18 14:17:29 | 2025-03-18 14:17:29 |
+----+-----------+---------+---------------------+---------------------+

5. 总结

在字段扩容时,如果原列已声明字符集和排序规则,应确保扩容后的列与原列保持一致。这不仅适用于不同版本的 OceanBase 数据库,还能避免字符集或因排序规则变更带来的潜在问题。

参考资料

[1]

ERROR 1235:

[2]

Online DDL:

本文关键字:#OceanBase# #字段扩容# #字符集#

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2025-04-01,如有侵权请联系 cloudcommunity@tencent 删除oceanbase排序数据库collationddl

OceanBase 字段扩容避坑:字符集变更导致 DDL 失败

作者:吕虎桥,爱可生 DBA 团队成员,主要负责 DMP 平台和 MySQL 数据库的日常运维及故障处理。

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文约 1100 字,预计阅读需要 3 分钟。

1. 背景

程序报错提示长度超过列长,需要扩容字段长度。在执行修改的时候报错 ERROR 1235 (0A000): Alter charset or collation type not supported,提示不支持字符集或排序规则变更。

数据库版本:OceanBase 3.2.3.0

2. 复现步骤

2.1 新建表

代码语言:javascript代码运行次数:0运行复制
create table user_info (
idbigintnotnull auto_increment primary keyCOMMENT'自增主键',
user_name varchar(30) CHARACTERSET utf8mb4 COLLATE utf8mb4_bin DEFAULTNULLCOMMENT'用户名',
address varchar(200) COMMENT'地址',
create_time datetime defaultcurrent_timestampCOMMENT'创建时间',
update_time datetime defaultcurrent_timestamponupdatecurrent_timestampCOMMENT'更新时间'
)defaultcharset utf8mb4;

2.2 修改表结构

代码语言:javascript代码运行次数:0运行复制
MySQL [mydb]> alter table user_info modify user_name varchar(50);
ERROR 1235 (0A000): Alter charset or collation type not supported

3. 问题分析

3.1 查看 MySQL 租户默认的字符集和排序规则

代码语言:javascript代码运行次数:0运行复制
MySQL [mydb]> show variableslike'%character%';
+--------------------------+---------+
| Variable_name            | Value   |
+--------------------------+---------+
| character_set_client     | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database   | utf8mb4 |
| character_set_filesystem | binary  |
| character_set_results    | utf8mb4 |
| character_set_server     | utf8mb4 |
| character_set_system     | utf8mb4 |
+--------------------------+---------+
7 rows in set (0.003 sec)

MySQL [mydb]> showvariableslike'%collation%';
+----------------------+--------------------+
| Variable_name        | Value              |
+----------------------+--------------------+
| collation_connection | utf8mb4_general_ci |
| collation_database   | utf8mb4_general_ci |
| collation_server     | utf8mb4_general_ci |
+----------------------+--------------------+

3.2 查看表和字段默认字符集、排序规则

代码语言:javascript代码运行次数:0运行复制
--查看表的默认字符集、排序规则
SELECT TABLE_NAME, CCSA.character_set_name AScharset, CCSA.collation_name AScollation
FROM INFORMATION_SCHEMA.TABLES T
    JOIN INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY CCSA
    ON T.table_collation = CCSA.collation_name
WHERE T.table_name = 'user_info';

+------------+---------+--------------------+
| TABLE_NAME | charset | collation          |
+------------+---------+--------------------+
| user_info  | utf8mb4 | utf8mb4_general_ci |
+------------+---------+--------------------+

--查看列默认字符集、排序规则
SELECT COLUMN_NAME, CHARACTER_SET_NAME AScharset, COLLATION_NAME AScollation
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'user_info'AND TABLE_SCHEMA = 'mydb';

+-------------+---------+--------------------+
| COLUMN_NAME | charset | collation          |
+-------------+---------+--------------------+
| id          | binary  | binary             |
| user_name   | utf8mb4 | utf8mb4_bin        |
| address     | utf8mb4 | utf8mb4_general_ci |
| create_time | binary  | binary             |
| update_time | binary  | binary             |
+-------------+---------+--------------------+

3.3 问题原因

在字段扩容的时候,没有声明列的排序规则,会自动继承表的排序规则 --> utf8mb4_general_ci,需要把列排序规则从 utf8mb4_bin 转换为 utf8mb4_general_ci,但是 OceanBase 3.2.3 不支持在线修改表的字符集、排序规则,更多参考[1]

3.4 解决方法

修改列的时候声明列的字符集、排序规则。

代码语言:javascript代码运行次数:0运行复制
MySQL [mydb]> alter table user_info modify user_name varchar(50) CHARACTERSET utf8mb4 COLLATE utf8mb4_bin DEFAULTNULLCOMMENT'用户名' ;
Query OK, 0 rows affected (0.050 sec)

MySQL [mydb]> showcreatetable user_info\G
*************************** 1.row ***************************
       Table: user_info
CreateTable: CREATETABLE`user_info` (
`id`bigint(20) NOTNULL AUTO_INCREMENT COMMENT'自增主键',
`user_name`varchar(50) CHARACTERSET utf8mb4 COLLATE utf8mb4_bin DEFAULTNULLCOMMENT'用户名',
`address`varchar(200) DEFAULTNULLCOMMENT'地址',
`create_time` datetime DEFAULTCURRENT_TIMESTAMPCOMMENT'创建时间',
`update_time` datetime DEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMPCOMMENT'更新时间',
  PRIMARY KEY (`id`)
) AUTO_INCREMENT = 1DEFAULTCHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0
1rowinset (0.009 sec)

4. 在 OceanBase 4.2.1 版本验证

代码语言:javascript代码运行次数:0运行复制
--查看数据库版本
MySQL [mydb]> select @@version;
+---------------------------+
| @@version                 |
+---------------------------+
| 5.7.25-OceanBase-v4.2.1.4 |
+---------------------------+

--修改列长度
MySQL [mydb]> alter table user_info modify user_name varchar(50) ;
Query OK, 0 rows affected (1.706 sec)

在 OceanBase 4.2.1 版本,字段长度扩容成功,列排序规则发生了变更,从 utf8mb4_bin 变更为 utf8mb4_general_ci

代码语言:javascript代码运行次数:0运行复制
SELECT COLUMN_NAME, CHARACTER_SET_NAME AScharset, COLLATION_NAME AScollation
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'user_info'AND TABLE_SCHEMA = 'mydb';

+-------------+---------+--------------------+
| COLUMN_NAME | charset | collation          |
+-------------+---------+--------------------+
| id          | NULL    | NULL               |
| user_name   | utf8mb4 | utf8mb4_general_ci |
| address     | utf8mb4 | utf8mb4_general_ci |
| create_time | NULL    | NULL               |
| update_time | NULL    | NULL               |
+-------------+---------+--------------------+

查看 OceanBase 官网,在 OceanBase 4.2.1 版本中列字段扩容属于 Online DDL[2],可以直接变更。但是这样就产生了一个潜在的风险,列排序规则变更为 utf8mb4_general_ci 会忽略大小写,可能会影响数据的一致性。

代码语言:javascript代码运行次数:0运行复制
MySQL [mydb]> insert into user_info (user_name,address) values ('Alice','上海');
Query OK, 1 row affected (0.051 sec)

MySQL [mydb]> insert into user_info (user_name,address) values ('alice','上海');
Query OK, 1 row affected (0.027 sec)

MySQL [mydb]> select * from user_info where user_name='alice';
+----+-----------+---------+---------------------+---------------------+
| id | user_name | address | create_time         | update_time         |
+----+-----------+---------+---------------------+---------------------+
|  1 | Alice     | 上海    | 2025-03-18 14:17:25 | 2025-03-18 14:17:25 |
|  2 | alice     | 上海    | 2025-03-18 14:17:29 | 2025-03-18 14:17:29 |
+----+-----------+---------+---------------------+---------------------+

5. 总结

在字段扩容时,如果原列已声明字符集和排序规则,应确保扩容后的列与原列保持一致。这不仅适用于不同版本的 OceanBase 数据库,还能避免字符集或因排序规则变更带来的潜在问题。

参考资料

[1]

ERROR 1235:

[2]

Online DDL:

本文关键字:#OceanBase# #字段扩容# #字符集#

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2025-04-01,如有侵权请联系 cloudcommunity@tencent 删除oceanbase排序数据库collationddl

本文标签: OceanBase 字段扩容避坑字符集变更导致 DDL 失败