
作者:吕虎桥,爱可生 DBA 团队成员,主要负责 DMP 平台和 MySQL 数据库的日常运维及故障处理。
爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
本文约 1100 字,预计阅读需要 3 分钟。

1. 背景
程序报错提示长度超过列长,需要扩容字段长度。在执行修改的时候报错 ERROR 1235 (0A000): Alter charset or collation type not supported
,提示不支持字符集或排序规则变更。
数据库版本:OceanBase 3.2.3.0
2. 复现步骤
2.1 新建表
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 修改表结构
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 租户默认的字符集和排序规则
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 查看表和字段默认字符集、排序规则
--查看表的默认字符集、排序规则
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 解决方法
修改列的时候声明列的字符集、排序规则。
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 版本验证
--查看数据库版本
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
。
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
会忽略大小写,可能会影响数据的一致性。
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 数据库,还能避免字符集或因排序规则变更带来的潜在问题。
ERROR 1235: https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000207750
[2]Online DDL: https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000252799
本文关键字:#OceanBase# #字段扩容# #字符集#


✨ Github:https://github.com/actiontech/sqle
📚 文档:https://actiontech.github.io/sqle-docs/
💻 官网:https://opensource.actionsky.com/sqle/
👥 微信群:请添加小助手加入 ActionOpenSource
🔗 商业支持:https://www.actionsky.com/sqle
