维护表和索引分区

1. ALTER FRAGMENT 语句

  如果想更改分片策略,可以使用ALTER FRAGMENT语句。

  • 初始化新的片段模式

ALTER FRAGMENT …INIT

  • 增加额外片段

ALTER FRAGMENT …ADD

  • 删除一个片段

ALTER FRAGMENT …DROP

  • 修改片段表达式或 dbspace

ALTER FRAGMENT …MODIFY

  • 将表合并至一张分片表中,或将片段移至独立的表中

ALTER FRAGMENT …ATTACH or DETACH

2. ALTER FRAGMENT如何被执行?

2.1 具有日志记录的数据库

  • ALTER FRAGMENT 将作为一个单独的事务被执行。
    被移动的每一行将作为逻辑日志中的一个条目。因为可能存在大量的日志条目,所以可能会导致长事务。对于非常大的表,考虑在更改分片模式时关闭日志记录,或者把语句分为小的 ALTER FRAGMENT 语句来执行。

  • 语句执行时整张表都将被独占锁定。

  • 如果一行被移至一个片段中,它将从旧位置被删除并被添加到新片段中。
    只要旧行被删除,旧行所占的磁盘空间将被立即释放,但是所在的extent仍然会保持分配直至完为空。无论是片段是要删除行还是添加行,都需要确保有足够的磁盘空间可以容纳片段。

2.2 没有日志记录的数据库

  • 旧片段将保持原封不动,直到 ALTER FRAGMENT 操作完成。 确保有足够的磁盘空间同时容纳旧的和新的片段。

  • 语句执行时整张表都将被锁定。

3. 初始化新的片段策略

  • 将一个分片的表变成非分片,要指定 dbspace 名称,用于放置非分片表

alter fragment on table table1 init in dbspace2;

  • 将一个非分片的表变成分片

alter fragment on table table1
init fragment by round robin
   in dbspace1, dbspace2;

  • 完全改变分片策略

alter fragment on table table1
init fragment by expression
  col_1 <= 10000 and col_1 >= 1 in dbspace1,
  col_1 <= 20000 and col_1 > 10000 in dbspace;

  • 使用分区表

alter fragment on table table1
init partition by expression
partition part1 col_1 between 0 and 5000 in dbspace1,
partition part2 col_1 > 5000 in dbspace2;

4. 添加新的分片

  使用 ADD子句为分片表添加新的分片。ADD 命令执行时,行将被打乱以遵守新的分片策略。

  • 表达式模式

alter fragment on table orders
add note_code >3000 in dbspace4;

alter fragment on table orders
add note_code <= 3000 or note_code = 3500
  in dbspace3 before dbspace4;

  这两个例子为基于表达式的片段增加了新的 dbspace。BEFORE 或 AFTER 子句用于在已有条件之前或之后插入新的条件。这可能非常重要,因为表达式内的条件将按顺序判定。新的条件不能被添加到remainder子句之后。如果 BEFORE 或 AFTER 未被指定,则 dbspace 将被添加到表达式的末尾,但位于remainder子句之前。

  • 为轮循分片模式新增一个 dbspace

alter fragment on table customer
add dbspace3;

  • 添加新的分区

alter fragment on table fj_customer
add partition part4 id>=20000 in datadbs1;

  在 ADD 关键字之后添加 PARTITION 关键字和分区名称,从而为已存在的表添加一个新的分区。

5. 删除片段

  使用 DROP 子句删除一个片段,并将该片段中所有的行 (或索引键)移至其他片段。

alter fragment on table table1
drop dbspace1;

alter fragment on index table1_idx1
drop dbspace4;

  确保另一个片段有足够的空间容纳将要移至此处的行。例如,在基于表达式模式的分片中,被删除片段中的行将很可能进入remainder片段。

  不允许将片段的数量减少到少于 2 个。

  为删除分区,请使用分区名称而不是其常驻的 dbspace。

6. 修改已有片段

  使用 MODIFY 子句修改片段的表达式或 dbspace。

alter fragment on table table1
modify dbspace1 to col_1 > 30000
  in dbspace1;

alter fragment on table table1
modify dbspace3 to remainder
  in dbspace5;

alter fragment on table table1
modify part1 to
  partition part1 col_1 > 30000
  in dbspace1;

  如果更改了表达式,已有片段中不匹配表达式的行将移至合适的分片中。如果对于一个被判定为假的表达式又不存在一个合适的分片,而某一行必须要被移动,则系统会返回错误,同时ALTER FRAGMENT 也会失败。

  为修改分区,请使用分区名称而不是其常驻的 dbspace。

7. 附加和分离表

  • 使用 ATTACH 子句将两个具有相同模式的的表组合成一个分片表。

alter fragment on table table1
attach table1, table2;

  • 使用 DETACH 分离分片表的一部分为未分片表。

alter fragment on table table1
detach dbspace2 table2;

alter fragment on table table1
detach partition part1 table2;

7.1 ATTACH

  可以使用 ATTACH 子句将两个相同的表组合成一个分片表。在上面的例子中,table1 和 table2 是两张表,它们被组合成一张表 table1。两个表必须具有相同的模式并且必须位于不同的 dbspace。在任何一张表中不允许出现引用、主键、唯一或者 NOT NULL 约束。被合并的表中不能含有序列(serial column),并且合并的表不能有check约束。

索引重建

  如果新增加的分片与表中已有是对称的,那么可以避免索引重建。

  • 在已经存在的表片段和新增加的片段中没有数据重合。

  • 新增片段的索引和目标表的索引必须建立在相同的列的集合上。

  • 新增片段的索引必须和目标表的索引具有相同的属性(unique、duplicate)。

  • 新增片段的索引不能位于目标表索引片段已经使用的 dbspace 中。

7.2 DETACH

  可以使用 DETACH 子句提取一个片段用于创建一个单独的表。一旦片段被分离,被创建的表将可以被删除。对于一组滚动 的按时间顺序维护的分片表,新片段会被添加,旧片段要被移除,在这种情况下DETACH尤其有用。

索引重建

  如果被分离片段的索引分片策略与分片表的索引分片策略相同或高度相似,则原始表上的索引重建是不必要的。在这种情况下,与分离片段对应的索引片段会直接被删除。

  需要注意的是,DETACH 命令对于使用 WITH ROWIDS 创建的表不起作用。

8. 跳过无法访问的片段

  SinoDB动态服务器允许使用SQL语句SET DATASKIP 或 DATASKIP 配置参数跳过无法访问的片段。

  • 打开 dataskip

SET DATASKIP ON ;

  • 关闭 dataskip

SET DATASKIP OFF ;

  • 跳过指定片段

SET DATASKIP dbspace1;

  • 使用配置参数DATASKIP设置的策略

SET DATASKIP DEFAULT;

以下情况下无法访问的分片将不能被跳过:

  • 引用完整性 – 为删除父行,子行也必须能被删除。为插入子行,父行必须可以访问。

  • 更新 – 更新操作需要将一行从一个分片移至另一个分片,要求两个分片都可以被访问。

  • 插入或删除 –一个必须被放于特定分片中的行(由于基于表达式的分片模式)要求该分片必须可以被访问。

  • 索引 – 如果 INSERT,UPDATE 或 DELETE 会影响索引键,该索引键必须可以被访问。

  • 序列键值 – 第一个片段存储当前的序列键值,要求下一个连续键值的insert操作需要用到第一个片段。。