Oceanbase(v4)同Oracle数据库一样支持BLOB、 CLOB和 NCLOB,LOB
类型是用于存储 TEXT、BLOB、JSON、Geometry 等数据类型。在OB与Oracle一样, LOB
的存储的方式分为内联存储(INROW)和外联存储(OUTROW)两种。对于inrow还是outrow的数据大小限制不同,在oracle中是如果 LOB 的大小大于约 4000 字节(4000 减去系统控制信息),无论列的 LOB 存储属性如何都会 out-of-line。 但是在OB中可以突破该限制,如LOB_INROW_THRESHOLD = 8192,LOB_INROW_THRESHOLD
表示 LOB 列的阈值。当 LOB 列的数据小于等于 8192 字节时,LOB 数据和主表行存储在一起。 当然Oracle LOB存储还支持BasicFiles /SecureFiles 在之前的笔记分享过LOB 不当的RETENTION 会导致严重的空间浪费(二). 同是当从oracle迁移到oceanbase时, 对于LOB对象还是要特别注意,我们常说的兼容不只是类型兼容、还有语法语义、形为兼容。如果目标的限制更宽松,可以接受,但是如果缩小了限制,会导致数据无法迁入目标数据库。
–env Oceanbase for oracle V3.2
从oracle迁移到OB的应用程序日志错误如下:
SQL=update xxx set lob_col=:xx where oid=:oid The size(18141152) is too large, location: 0 mallocator.cpp(308) dbconnect error oci _error code:100203, msg: the request message The size(18141152) is too large Error-oci _error code:100203, msg: the request message The size(18141152) is too large
查看列定义lob_col BLOB data type, 使用dbms_lob.getlength(lob_col) 确认当前入库的最大也就在 ≈ 18MB 左右。
在上一篇《Oracle MySQL PostgreSQL BLOB & CLOB maximum size Limit》记录过,Oracle 中 CLOB 和 BLOB 类型均可达到 4G 大小,如果这样就OB没办法完全兼容oracle. 在OB 的官方文档
OceanBase 数据库V3 版本所支持的大对象数据类型的信息如下表所示:
类型 | 长度 | 定义长度上限(字符) | 字符集 |
BLOB | 变长 | 48 MB | BINARY |
CLOB | 变长 | 48 MB | 与租户的字符集一致 |
在 OceanBase 早期的版本中,LOB 数据存储大小限制在 48MB 以内,但如上面的案例,实际BLOB在写入18M左右就报错了,这对客户使用 LOB 带来了强约束限制。在V4后,通过存储层将 Lob 宏块的数据拆成多条 Lob Meta 进行存储,取数据的时候再将多条 Lob Meta 中的数据聚合成一个连续 Buffer 返回给 SQL 层处理,这样突破了数据存储大小的限制,使得 LOB 存储上限扩展达到了 512MB,后续将持续优化到 TB 级别(暂不确认哪个版本可以实现)。
OB V4 for oracle
类型 | 最大长度 |
---|---|
CHAR |
2000 字节 |
NCHAR |
2000 字节 |
VARCHAR |
32767 字节 |
VARCHAR2 |
32767 字节 |
NVARCHAR2 |
32767 字节 |
BLOB |
536870910 字节 |
CLOB |
536870910 字节 |
目前的OB V4.2中LOB的上限提升到512MB, 如果从oracle迁移前,确定在OB支持的最大长度范围内,可以直迁。超出最大范围需要业务改造,我们某客户直接删除了超长记录0_0!。在v3中OB不支持 NCLOB,需要使用NVARCHAR2(32767 bytes max size limit)替换。
统计CLOB 和 BLOB 字段的最大值:
SELECT MAX(DBMS_LOB.GETLENGTH(COL_CLOB)) AS MAX_CLOB, MAX(DBMS_LOB.GETLENGTH(COL_BLOB)) AS MAX_BLOB FROM tablexxx
— enjoy —