本节阐述了对使用范围和区间分片作为其分布策略的表使用 ALTER FRAGMENT 语句的 MODIFY 子句的语法的功能和 MODIFY 子句可更改内容的限制。
有关按列表分片的表使用 MODIFY 子句的类似的示例,请参阅列表分片的 MODIFY 子句的示例 。
此语句禁用范围区间分片的创建:
ALTER FRAGMENT ON TABLE tab MODIFY INTERVAL DISABLED;
以下语句恢复范围区间分片的创建,撤销了前一个例子的作用:
ALTER FRAGMENT ON TABLE tab MODIFY INTERVAL ENABLED;
以下语句禁用范围区间分片创建,并修改了 dbspace 列表(在 STORE IN 语句中表明了存储新分片的 dbspace )。如果随后的 ALTER FRAGMENT MODIFY 语句启用了 tab 表的范围区间分片创建功能。
ALTER FRAGMENT ON TABLE tab MODIFY INTERVAL DISABLED STORE IN (dbs4, dbs5);
此语句重命名两个范围区间分片。没有指定新存储位置的 IN 子句,因此两个分片新的名称替代了现有的名称:
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p1 TO PARTITION newp1, PARTITION sys_p6 TO PARTITION newsys_p6;
范围区间分片需要 PARTITION 关键字。如果您使用 MODIFY 子句重命名现有的分片,那么在 MODIFY 子句中声明的新的名称不能以字符串 sys 开头(该字符串用于系统定义的分片), 以上示例成功地重命名了系统定义的分片 sys_p6 。
CREATE TABLE tab2 (i INT, c CHAR(2)) FRAGMENT BY RANGE (i) INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) PARTITION p0 VALUES < 100 IN dbs0, PARTITION p1 VALUES < 200 IN dbs1; INSERT INTO tab2 VALUES (201, "AA"); -- creates a system-generated interval fragment sys_p2 -- with fragment expression >= 200 AND < 300 -- assume that this fragment is created in dbs1 INSERT INTO tab2 VALUES (601, "BB"); -- creates a system-generated interval fragment sys_p6 -- with fragment expression >= 600 AND < 700 ---assume that this fragment is created in dbs2以下语句标示了数据库服务器将范围分片 p1 从 dbs1 移动到 dbs2:
ALTER FRAGMENT ON TABLE tab2 MODIFY PARTITION p1 TO PARTITION p1 IN dbs2;下一示例将范围分片 p1 从 dbs1 移动到 dbs2 并将区间分片 sys_p6 从 dbs2 移动到 dbs3:
ALTER FRAGMENT ON TABLE tab2 MODIFY PARTITION p1 TO PARTITION p1 IN dbs2, PARTITION sys_p6 TO PARTITION sys_p6 IN dbs3;
CREATE TABLE tab (i INT, c CHAR(2)) FRAGMENT BY RANGE (i) INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) PARTITION p0 VALUES < 100 IN dbs0, PARTITION p1 VALUES < 200 IN dbs1;下列 ALTER FRAGMENT 语句在 STORE IN 中用新的列表 (dbs4 、dbs5)替换了列表(dbs1 、dbs2 、dbs3)。
ALTER FRAGMENT ON TABLE tab MODIFY INTERVAL STORE IN (dbs4, dbs5);
上个示例中,MODIFY 子句指定了新的分片将会轮流创建于 dbs4 和 dbs5 中。任何创建在最初 STORE IN 列的 dbspace (dbs1 、dbs2 、dbs3) 中的系统定义的分片(和分片 p1) 仍保留在这些 dbspace 中。现有的和随插入行之后的分片键在这些分片范围区间内的分片仍将继续存储在这些分片中,但是将会创建新的区间分片,轮流地存储于 dbs4 和 dbs5 dbspace 中。
CREATE TABLE mytab (col1 int) FRAGMENT BY RANGE (c1) INTERVAL (100) STORE IN (dbs1, dbs2, dbs3, dbs4, dbs5) PARTITION p1 VALUES < 300 in dbs0;此 ALTER FRAGMENT 语句替换了存储新区间分片的 dbspace 列表:
ALTER FRAGMENT ON TABLE mytab MODIFY STORE IN (dbs1, dbs6, dbs3, dbs4, dbs8);新的列表用 dbs6 代替了 dbs2 ,dbs8 替换了 dbs5。如果您希望来自当前 STORE IN 列表的任何 dbspace 可用于新的分片,那么 MODIFY 子句必须在新的列表(在已修改的分片存储方案中替换了旧的列表)中包含它们。在上述示例中,新区间分片将在 STORE IN 关键字之后列出的五个 dbspace 中创建 ,但是任何创建于 dbs2 和 dbs5 中的现有的分片将继续存储数据值符合分片键值范围的分片的行。
您可以在 STORE IN 子句中修改 dbspace 的列表。旧的列表会被您指定的新的列表所替换。不会移动旧的 dbspace 中的分片。考虑下表:
您可以通过更改该分片的 IN dbspace 规范而将现有分片移动到另一个 dbspace :
CREATE TABLE tab (i INT, c CHAR(2)) FRAGMENT BY RANGE (i) INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) PARTITION p0 VALUES < 100 IN dbs0, PARTITION p1 VALUES < 200 IN dbs1; INSERT INTO tab VALUES (201, "AA"); -- creates interval fragment sys_p2 -- with fragment expression >= 200 AND < 300 -- (assume that this fragment is created in dbs1) INSERT INTO tab VALUES (601, "BB"); -- creates interval fragment sys_p6 -- with fragment expression >= 600 AND < 700 -- (assume that this fragment is created in dbs2)下一个语句指示数据库服务器将分片 p1 从 dbs1 移动到 dbs2 :
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p1 TO PARTITION p1 IN dbs2;以下示例将范围分片 p1 从 dbs1 移动到 dbs2 ,并将区间分片 sys_p6 从 dbs2 移动到 dbs3 :
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p1 TO PARTITION p1 IN dbs2, PARTITION sys_p6 TO PARTITION sys_p6 IN dbs3;然而,当系统生成分片后,您不能修改该区间分片的表达式。考虑此表:
CREATE TABLE tab (i INT, c CHAR(2)) FRAGMENT BY RANGE (i) INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) PARTITION p0 VALUES < 100 IN dbs0, PARTITION p1 VALUES < 200 IN dbs1; INSERT INTO tab VALUES (201, "AA"); -- creates interval fragment sys_p2 -- with fragment expression >= 200 AND < 300 INSERT INTO tab VALUES (601, "BB"); -- creates interval fragment sys_p6 -- with fragment expression >= 600 AND < 700现在您不能修改 sys_p2 或 sys_p6 的分片表达式。如果您尝试修改,则会返回错误。
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION sys_p6 TO PARTITION sys_p6 VALUES < 900 IN dbs2;上述语句失败并发生了错误。
CREATE TABLE tab (i INT, c CHAR(2)) FRAGMENT BY RANGE (i) INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) PARTITION p0 VALUES < 100 IN dbs0, PARTITION p1 VALUES < 200 IN dbs1; INSERT INTO tab VALUES (201, "AA"); -- creates interval fragment sys_p2 -- with fragment expression >= 200 AND < 300 INSERT INTO tab VALUES (601, "BB"); -- creates interval fragment sys_p6 -- with fragment expression >= 600 AND < 700现在您不能修改区间分片 sys_p2 或 sys_p6 的表达式。如果您尝试修改,则会返回错误。
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION sys_p6 TO PARTITION sys_p6 VALUES < 900 IN dbs2;以上语句因产生错误而失败。
CREATE TABLE tab (i INT, c CHAR(2)) FRAGMENT BY RANGE (i) INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) PARTITION p0 VALUES < 100 IN dbs0, PARTITION p1 VALUES < 200 IN dbs1, PARTITION p2 VALUES < 300 IN dbs0; INSERT INTO tab VALUES (301, "AA"); -- creates interval fragment sys_p3 -- with fragment expression >= 300 AND < 400 INSERT INTO tab VALUES (601, "BB"); -- creates interval fragment sys_p6 -- with fragment expression >= 600 AND < 700以下所有的 ALTER 示例都基于上述 CREATE 语句中定义的表的分片。下列 ALTER FRAGMENT 语句修改了范围分片 p0 的表达式:
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p0 TO PARTITION p0 VALUES < -50 IN dbs0;以下语句修改了分片 p0 的表达式并将此分片从 dbs0 移动到 dbs5 :
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p0 TO PARTITION p0 VALUES < -50 IN dbs5;下列语句成功地完成了对分片 p0 的三次更改:
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p0 TO PARTITION newp0 VALUES < -50 IN dbs5;然而,下一示例因产生错误而失败,因为分片 p0 的新表达式超越了下一个相邻分片 p1 的范围的边界:
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p0 TO PARTITION p0 VALUES < 250 IN dbs0;以下 ALTER FRAGMENT 示例成功地修改了范围分片 p1 的表达式:
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p1 TO PARTITION p1 VALUES < 150 IN dbs1;以下修改因产生错误而失败,因为分片 p1 的新表达式超越了前一个相邻分片 p0 的范围的边界:
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p0 TO PARTITION p0 VALUES < 50 IN dbs0;出于某种原因,ALTER FRAGMENT MODIFY 操作失败,行无法移动到新的分片中,并返回了错误。 示例如下:
CREATE TABLE tab (i INT, c CHAR(2)) FRAGMENT BY RANGE (i) INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) PARTITION p0 VALUES IS NULL IN dbs0, PARTITION p1 VALUES < 200 IN dbs1, PARTITION p2 VALUES < 300 IN dbs0; ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p0 TO PARTITION p0 VALUES < 100 IN dbs0;由于进行了修改,生成的表具有以下分片:
PARTITION p0 VALUES < 100 IN dbs0, PARTITION p1 VALUES < 200 IN dbs1, PARTITION p2 VALUES < 300 IN dbs0如果之前的 NULL 分片存储了行(意味着表中的列 i 的有 NULL值行),那么这些行不适合此新分片结构中的任何分片。当移动行时,上述的 ALTER FRAGMENT 操作将因此失败。
CREATE TABLE tab (i INT, c CHAR(2)) FRAGMENT BY RANGE (i) INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) PARTITION p0 VALUES IS NULL IN dbs0, PARTITION p1 VALUES < 200 IN dbs1, PARTITION p2 VALUES < 300 IN dbs0;假设该表在分片 p0 中没有行。在这种情况下,p0 能被更改为非 NULL 分片。
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p0 TO PARTITION p0 VALUES < 250 IN dbs0;然而,因为 p0(VALUES < 250)的新的表达式超越了 p1(VALUES < 200)的临界,以上示例返回了错误。
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p0 TO PARTITION p0 VALUES < 150 IN dbs0;您可以修改最后一个范围分片的表达式(过渡分片)但是只能增加过渡值。在此操作中没有数据移动。
CREATE TABLE tab (i INT, c CHAR(2)) FRAGMENT BY RANGE (i) INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) PARTITION p0 VALUES < 100 IN dbs0, PARTITION p1 VALUES < 200 IN dbs1, PARTITION p2 VALUES < 300 IN dbs0; -- last range fragment or transition fragment以下修改返回错误。因为它尝试减少过渡值(从 300 变更为 250):
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p2 TO PARTITION p2 VALUES < 250 IN dbs0;以下语句修改了 p2(过渡分片)的分片表达式。因为还没有系统生成的区间分片,新的过渡值不需要与区间分片标记对齐。
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p2 TO PARTITION p2 VALUES < 350 IN dbs0;如果在新的和旧的过渡值之间没有区间分片,您可以将最后一个范围分片的表达式修改为 VALUES < new transition value。示例如下:
CREATE TABLE tab (i INT, c CHAR(2)) FRAGMENT BY RANGE (i) INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) PARTITION p0 VALUES < 100 IN dbs0, PARTITION p1 VALUES < 200 IN dbs1, PARTITION p2 VALUES < 300 IN dbs0; -- last range fragment is the "transition fragment" INSERT INTO tab VALUES (601, "BB"); -- creates interval fragment sys_p6 -- with fragment expression >= 600 AND < 700 -- (assume that this fragment is created in dbs3)已修改的表现在具有这些分片:
在更改过渡值的过程中,分片以不会产生数据移动的方式修改。
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p2 TO PARTITION p2 VALUES < 500 IN dbs0;旧的过渡值是 300 ,新的过渡值是 500 。在这些范围分片中没有系统生成的区间分片,第一个区间分片的起始值为 600 。这也意味着在 300 和 500 之间没有数据行,因此此过渡分片(最后一个范围分片)的表达式可以修改为 VALUES < 500 而不用数据移动。因为在新的过渡值后没有区间分片,所以新过渡值必须与区间分片边界对齐。在这种情况下,新的过渡值 500 与区间分片的边界对齐(此区间分片不须存在)。
此修改的结果是,随后的区间分片的 evalpos 值改变,区间分片重命名为符合系统生成的分片的名称的格式。此 ALTER TABLE MODIFY 操作后,产生的表具有这些分片:
这是分片 p2 (最后一个范围分片)已修改的表达式。(也就是 transition fragment ,因为任何存储了大于分片键范围的值的分片将会是系统生成的区间分片。)系统生成的区间分片重命名为 sys_p4 ,因为过渡分片的表达式更改后,evalpos 值从 6 变为 4 。
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p2 TO PARTITION p2 VALUES YY 550 IN dbs0;区间分片的范围可以是 300 到 400 、400 到 500 、500 到 600 、600 到 700 等等,但是新的过渡值 550 不在区间分片的边界,因此数据库服务器会声明错误。
如果在新的和旧的过渡值之间有区间分片,那么新过渡值必须与区间分片的边界对齐(该区间分片不须存在),除非新过渡值超过了最后一个区间分片。所有在新的和旧的过渡值之间的分片会被转换为范围分片,它们的表达式会被修改以符合范围分片表达式。最后一个区间分片的表达式转换为范围分片,更改为 VALUES < new transition value 。
CREATE TABLE tab (i INT, c CHAR(2)) FRAGMENT BY RANGE (i) INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) PARTITION p0 VALUES < 100 IN dbs0, PARTITION p1 VALUES < 200 IN dbs1, PARTITION p2 VALUES < 300 IN dbs0; -- last range fragment or transition fragment INSERT INTO tab VALUES (301, "AA"); -- creates interval fragment sys_p3 -- with fragment expression >= 300 AND < 400 -- (assume this fragment is created in dbs1) INSERT INTO tab VALUES (601, "BB"); -- creates interval fragment sys_p6 -- with fragment expression >= 600 AND < 700 -- (assume this fragment is created in dbs3)在两个 INSERT 操作之后,该表将具有这些范围和区间分片:
以下的 ALTER FRAGMENT 示例基于此表。
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p2 TO PARTITION p2 VALUES < 500 IN dbs0;
因为在旧过渡值和新过渡值之间有一个区间分片(sys_p3),所以此分片转换为范围分片(其表达式变为 VALUES < 400)。
而且由于有超过新过渡值的区间分片(例如:分片 sys_p6),新过渡值必须与区间分片边界对齐,可能的区间分片必须是范围区间大小的整数倍(包括 400 到 500 、500 到 600 、700 到 800 等待)。新过渡值是 500 ,是一个区间分片的临界。它也可以在更改过渡分片期间有效避免移动数据和避免创建分片。这可能通过以下操作实现,将分片 sys_p3 转换为新的过渡分片,将它的表达式变更为 < 500 ,并重命名旧过渡分片的名称。
生成的表具有以下分片:
以下对过渡分片 p2 的修改返回了错误:
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p2 TO PARTITION p2 VALUES < 550 IN dbs0;
出现此错误的原因是有一个超过过渡值的区间分片 sys_p6,并且新过渡值不与区间分片边界对齐。
ALTER FRAGMENT ON TABLE tab MODIFY PARTITION p2 TO PARTITION p2 VALUES < 750 IN dbs0;
因为没有区间分片超过新过渡值,它不须与区间分片边界对齐。
产生的表具有以下分片: