建表分区有问题

【 使用环境 】测试环境
【 OB or 其他组件 】ob,navicat
【 使用版本 】
【问题描述】

【复现路径】问题出现前后相关操作
【附件及日志】推荐使用OceanBase敏捷诊断工具obdiag收集诊断信息,详情参见链接(右键跳转查看):

【SOP系列 22 】——故障诊断第一步(自助诊断和诊断信息收集)

【备注】基于 LLM 和开源文档 RAG 的论坛小助手已开放测试,在发帖时输入 [@论坛小助手] 即可召唤小助手,欢迎试用!

根据您提供的信息,您在创建分区表时遇到了问题。具体错误信息为 “This partition function is not allowed”,这表明您使用的分区函数不被允许。

根据文档库中的信息,错误码 4398 描述了类似的情况,即在创建分区表时使用了不兼容的分区方式。虽然您的错误码不是 4398,但问题的本质可能是相似的。以下是针对您的情况的具体分析和建议:

问题分析

  1. 分区函数不被允许
    • 您在 PARTITION BY RANGE 子句中使用了 CAST(EBELN AS UNSIGNED) 作为分区表达式。这种表达式可能不被 OceanBase 支持。

解决方法

  1. 检查分区表达式

    • 确保分区表达式是被支持的。通常,分区表达式应该是简单的列名或者一些基本的算术表达式。您可以尝试使用一个简单的列名作为分区表达式,而不是复杂的 CAST 函数。
  2. 修改分区方式

    • 如果您确实需要使用 CAST 函数,可以考虑其他分区方式,例如 HASHKEY 分区。这些分区方式通常对表达式的限制较少。

示例代码

以下是一个使用简单列名作为分区表达式的示例:

CREATE TABLE EKKO_RANGE (
    MANDT VARCHAR(10),
    EBELN VARCHAR(20),
    PRIMARY KEY (EBELN)
)
PARTITION BY RANGE (EBELN) (
    PARTITION p0 VALUES LESS THAN ('2100000127'),
    PARTITION p1 VALUES LESS THAN ('2100000327'),
    PARTITION p2 VALUES LESS THAN ('2188889527')
);

注意事项

  • 数据类型:确保 EBELN 列的数据类型与分区值的数据类型一致。
  • 分区值:确保分区值是有效的,并且按照从小到大的顺序排列。

如果您仍然遇到问题,建议您联系 OceanBase 的技术支持人员进行进一步的排查和协助。希望这些建议对您有所帮助!

具体信息可参考以下文档:

  1. 5000 ~ 5999
  2. 0001 ~ 3999
  3. 4000 ~ 4499
  4. 6000 ~ 6999
  5. 4500 ~ 4999

你的ob版本是哪个?执行的建表语句 能发一下么?

CREATE TABLE EKKO_RANGE (
MANDT VARCHAR(10),
EBELN VARCHAR(20),
PRIMARY KEY (EBELN)
)
PARTITION BY RANGE (LENGTH(EBELN))
(
PARTITION p1 VALUES LESS THAN (10),
PARTITION p2 VALUES LESS THAN (15),
PARTITION p3 VALUES LESS THAN MAXVALUE
);

4.3mysql兼容版本

根据您提供的 SQL 语句和使用环境,您在创建分区表时使用了 LENGTH(EBELN) 作为分区表达式。在 MySQL 模式下,分区表达式必须返回一个整数类型的结果。LENGTH(EBELN) 返回的是字符串 EBELN 的长度,这是一个整数,因此理论上是可以作为分区表达式的。

然而,根据文档片段 1 的描述,在 MySQL 模式中,PARTITION BY RANGE (expr) 里的 expr 表达式的结果必须为整型。虽然 LENGTH(EBELN) 返回的是整型,但某些特定的表达式可能仍然不被支持。

解决方法

  1. 简化分区表达式

    • 尝试使用一个简单的列名作为分区表达式,而不是复杂的函数表达式。
  2. 使用其他分区方式

    • 如果您确实需要使用 LENGTH(EBELN) 作为分区表达式,可以考虑其他分区方式,例如 HASHKEY 分区。

示例代码

以下是一个使用简单列名作为分区表达式的示例:

CREATE TABLE EKKO_RANGE (
    MANDT VARCHAR(10),
    EBELN VARCHAR(20),
    PRIMARY KEY (EBELN)
)
PARTITION BY RANGE (EBELN)
(
    PARTITION p1 VALUES LESS THAN ('10'),
    PARTITION p2 VALUES LESS THAN ('15'),
    PARTITION p3 VALUES LESS THAN MAXVALUE
);

注意事项

  • 数据类型:确保 EBELN 列的数据类型与分区值的数据类型一致。
  • 分区值:确保分区值是有效的,并且按照从小到大的顺序排列。

使用 LENGTH 函数的变通方案

如果您确实需要根据字符串长度进行分区,可以考虑在插入数据时使用一个额外的整数列来存储字符串长度,然后使用该列进行分区。例如:

CREATE TABLE EKKO_RANGE (
    MANDT VARCHAR(10),
    EBELN VARCHAR(20),
    EBELN_LENGTH INT GENERATED ALWAYS AS (LENGTH(EBELN)) STORED,
    PRIMARY KEY (EBELN)
)
PARTITION BY RANGE (EBELN_LENGTH)
(
    PARTITION p1 VALUES LESS THAN (10),
    PARTITION p2 VALUES LESS THAN (15),
    PARTITION p3 VALUES LESS THAN MAXVALUE
);

在这个示例中,EBELN_LENGTH 是一个生成列,自动计算 EBELN 的长度,并存储在表中。然后使用 EBELN_LENGTH 作为分区表达式。

结论

根据文档库中的信息,PARTITION BY RANGE 的表达式必须返回一个整型结果。虽然 LENGTH(EBELN) 返回的是整型,但某些特定的表达式可能仍然不被支持。建议您尝试使用简单的列名作为分区表达式,或者使用生成列来存储字符串长度,然后进行分区。

希望这些建议对您有所帮助!如果问题仍然存在,建议您联系 OceanBase 的技术支持人员进行进一步的排查和协助。

具体信息可参考以下文档:

  1. 创建分区表

(小助手的答复已结束,如未能解决您的问题,请继续提问并等待其他同学的回复,谢谢!)

你发的两个创建的语句 目前mysql都是不支持的 obmysql也不支持 目前和mysql保持一致