问题描述
往 OceanBase 数据库 MySQL 表中含有 LONGTEXT 的字段插入超出其设计的字符长度上限则会报错。
ERROR 1406 (22001): Data too long for column 'r4' at row 1
示例如下。
obclient [db_mysql]> insert into text1(id,r4) values (4,rpad('a',pow(2,28)-1,'z'));
ERROR 1406 (22001): Data too long for column 'r4' at row 1
适用版本
OceanBase 数据库 V2.x 和 V3.x 版本。
问题原因
OceanBase 数据库 LONGTEXT 字段设计存储最大字符个数比 MySQL 短,导致不兼容问题。
OceanBase 数据库 MySQL 模式下的 LONGTEXT 数据类型最大长度为 50331648 或 48M 个字符的 TEXT 类型。对应源码中定义如下。
const int64_t OB_MAX_TINYTEXT_LENGTH = 256; // mysql (1LL << 8)
const int64_t OB_MAX_TEXT_LENGTH = 64 * 1024L; // mysql (1LL << 16)
const int64_t OB_MAX_MEDIUMTEXT_LENGTH = 16 * 1024 * 1024L; // mysql (1LL << 24)
const int64_t OB_MAX_LONGTEXT_LENGTH = 48 * 1024 * 1024L; // mysql (1LL << 32)
其中 TINYTEXT、TEXT、MEDIUMTEXT 和 MySQL 中定义一致;LONGTEXT 数据类型设计最大字符长度比 MySQL 要短的多,MySQL 的 LONGTEXT 数据类型最大长度为 4GB。
MySQL 数据库示例
查询 max_allowed_packet 值。
mysql> select @@max_allowed_packet;输出结果如下。
+----------------------+ | @@max_allowed_packet | +----------------------+ | 1073741824 | +----------------------+ 1 row in set (0.00 sec)创建测试表。
mysql> create table text1 (id int primary key, r1 tinytext,r2 text, r3 mediumtext, r4 longtext); Query OK, 0 rows affected (0.05 sec)插入数据。
mysql> insert into text1(id,r1) values (1,rpad('a',pow(2,8)-1,'z')); Query OK, 1 row affected (0.03 sec)mysql> insert into text1(id,r2) values (2,rpad('a',pow(2,16)-1,'z')); Query OK, 1 row affected (0.02 sec)mysql> insert into text1(id,r3) values (3,rpad('a',pow(2,24)-1,'z')); Query OK, 1 row affected (1.25 sec)mysql> insert into text1(id,r4) values (4,rpad('a',pow(2,28)-1,'z')); Query OK, 1 row affected (39.95 sec)
OceanBase 数据库 MySQL 模式示例
查询 max_allowed_packet 值。
obclient [db_mysql]> select @@max_allowed_packet;输出结果如下。
+----------------------+ | @@max_allowed_packet | +----------------------+ | 1073741824 | +----------------------+ 1 row in set (0.004 sec)插入数据。
obclient [db_mysql]> insert into text1(id,r1) values (1,rpad('a',pow(2,8)-1,'z')); Query OK, 1 row affected (0.046 sec)obclient [db_mysql]> insert into text1(id,r2) values (2,rpad('a',pow(2,16)-1,'z')); Query OK, 1 row affected (0.030 sec)obclient [db_mysql]> insert into text1(id,r3) values (3,rpad('a',pow(2,24)-1,'z')); Query OK, 1 row affected (0.826 sec)obclient [db_mysql]> insert into text1(id,r4) values (4,rpad('a',pow(2,28)-1,'z')); ERROR 1406 (22001): Data too long for column 'r4' at row 1
解决方法
限制插入字符总长度在 LONGTEXT 数据类型定义最大长度 50331648 以内。
obclient [db_mysql]> insert into text1(id,r4) values (4,rpad('a',48*1024*1024-1,'z'));
Query OK, 1 row affected (2.906 sec)