DETACH子句使用ALTERFRAGMENTONTABLE语句的DETACH子句以将表分片从分布方案拆离,并将这些内容放入新的未分片表中。此子句在ALTERFRAGMENTONI
DETACH 子句
使用 ALTER FRAGMENT ON TABLE 语句的 DETACH 子句以将表分片从分布方案拆离,并将这些内容放入新的未分片表中。
此子句在 ALTER FRAGMENT ON INDEX 语句中无效。
有关分布方案的说明,请参阅 FRAGMENT BY 子句 。
DETACH 子句
元素 | 描述 | 限制 | 语法 |
fragment | 包含要拆离的表分片的分片或 dbspace 的名称。 | 执行时必须存在。 对于列表或范围区间分片, PARTITION 关键字必须产生 fragment。 | 标识符 |
new_table | 执行 ALTER FRAGMENT 语句后产生的未分片表的名称。 | 执行前必须存在 | 标识符 |
用法
执行 DETACH 子句而生成的新表不会从最初的表继承任何索引或约束。只保留数据值。
类似地,新表不从最初的表继承任何特权。而是具有任何新表都有的缺省特权。关于缺省表级别特权的进一步信息,请参阅 表级权限 中的 GRANT 语句。
DETACH 子句无法应用到以下具有任一属性的表中:
l 定义了 ROWID 列
l 定义了一列或队列为参考约束的主键
l 表中定义了 Enterprise Replication 复制
l 具有拆离索引(即,存储分布方案的索引与表的分片策略不同)
如果省略 PARTITION 关键字,那么分片的名称就是存储分片的 dbspace 的名称。
在以下示例中,系统生成的范围区间分片 sys_pt1 从表 T1 拆离并放置到新的未分片表 detacht1 中:
ALTER FRAGMENT ON TABLE T1 DETACH PARTITION sys_pt1 detacht1;
下一示例为从表 T2 拆离了列表分片 part2 并将其数据放置到新的未分片表 detacht2 中:
ALTER FRAGMENT ON TABLE T2 DETACH PARTITION part2 detacht2;
DETACH 操作后的分布统计信息
某些 ALTER FRAGMENT . . . DETACH 操作可能导致数据库服务器更新初始表的索引结构。当在这种情况下重建索引时,数据库服务器也将重新计算相关联列的分布方案,并且当其为拆离分片的表设置查询计划时这些统计信息可用于查询优化器:
l 对于在 ALTER FRAGMENT ... DETACH 自动重建 B-tree 索引的索引的列(或列的集合),重新计算的列分布统计信息相当于在 HIGH 模式下 UPDATE STATISTICS 语句创建的分布。
l 如果重建索引不是 B-tree 索引,对应自动重新计算的分布统计信息由 UPDATE STATISTIC 语句在 LOW 模式下创建。
如果启用更新列分布统计信息的自动模式,而且来自正在拆离分片的表具有分片级别分布统计信息,那么数据库服务器使用拆离的分片的统计信息作为新表的分布统计信息。数据库服务器也合并驻留分片数据分布统计信息以计算初始表的新表分布统计信息,并会将结果存储在 sysdistrib 系统目录表中。新表的分布统计信息的注册和旧表的表分布统计的重新计算都在后台运行。
有关在现有表中创建索引或约束时自动生成统计分布的语句的其他信息,请参阅自动计算分布统计信息中的 CREATE INDEX 语句的描述。
在 DETACH 操作中使用 ONLINE 关键字
ONLINE 关键字指示数据库服务器内部提交 ALTER FRAGMENT ... DETACH 工作,如果没有错误那么在要拆离分片的表上放置意向互斥锁而不是互斥锁。互斥锁可应用在从拆离分片创建的表上。
您只能对使用范围区间分片结构的表使用 ALTER FRAGMENT ONLINE ON TABLE 语句的 DETACH 选项。
使用范围区间存储分布方案的表具有两种类型的分片:
l range 分片,由 CREATE TABLE 或 ALTER TABLE 语句的 FRAGMENT BY 或 PARTITION BY 子句的用户定义
l interval 分片,如果具有超出过渡分片值上限(最后一个范围分片)的分片键值的行,那么数据库服务器在 INSERT 和 UPDATE 操作中自动生成该分片。
ONLINE DETACH 操作中只能拆离一个区间分片。
如果已拆离的区间分片不是最后一个分片,那么数据库服务器修改系统生成的遵循分片列表以匹配活表中它们的新的 sysfragments.evalpos 值的拆离分片的名称。在重命名此分片的操作中,当 sysfragments 系统目录正在用新的 partition 名称更新时,在分片上放置互斥锁(并且在 ALTER FRAGMENT DETACH 操作过程中,为在分片列表中变更初始位置的任何分片使用新 evalpos 值)。
活表上所有的索引必须与该表具有相同的分片结构。(即,任何索引必须可连接)由于这个原因,如果此表有主键约束或其它参考约束,那么建议您首先创建为该约束连接索引,然后使用 ALTER TABLE 语句添加该约束。(缺省情况下,主键约束的系统创建索引和其它已拆离的参考约束。)
如果有会话正在访问要拆离的同一分区,建议您声明 SET LOCK MODE TO WAIT 语句来获得保护非互斥存取错误足够的时间。
其它应用于 DETACH 选项的限制同样适用于 ONLINE DETACH 操作。有关这些限制,请参阅 对 ALTER FRAGMENT 语句的限制 和 DROP 子句。
ALTER FRAGMENT ONLINE ... DETACH 的示例
以下 SQL 语句定义了一个分片表 employee ,它使用范围区间存储分布方案,在列 emp_id(也是分片键)上有一个唯一索引 employee_id_idx 在列 dept_id 上有另一个索引。
CREATE TABLE employee (emp_id INTEGER, name CHAR(32), dept_id CHAR(2),
mgr_id INTEGER, ssn CHAR(12))
FRAGMENT BY RANGE (emp_id)
INTERVAL (100) STORE IN (dbs1, dbs2, dbs3, dbs4)
PARTITION p0 VALUES <200 IN dbs1,
PARTITION p1 VALUES <400 IN dbs2;
CREATE UNIQUE INDEX employee_id_idx ON employee(emp_id);
CREATE INDEX employee_dept_idx ON employee(dept_id);
INSERT INTO employee VALUES (401, "Susan", "DV", 101, "123-45-6789");
INSERT INTO employee VALUES (601, "David", "QA", 104, "987-65-4321");
最后两条语句使用超出过渡分片上限的分片键值插入了行,这导致数据库服务器生成了两个新区间分片,以致于生成包含四个分片的分片列表:
Fragments in surviving table before ALTER FRAGMENT ONLINE:
p0 VALUES <200 - range fragment
p1 VALUES <400 - range fragment (transition fragment)
sys_p2 VALUES >= 400 AND VALUES <500 - interval fragment
sys_p4 VALUES >= 600 AND VALUES <700 - interval fragment
以下语句返回了错误,因为指定的要拆离的分片是范围分片(分片存储的行的分片键值低于过渡值 400)。只有区间分片才能联机拆离。
ALTER FRAGMENT ONLINE ON TABLE employee
DETACH PARTITION p0 employee3;
以下语句成功运行,并创建了新表 employee3 以存储已拆离的分片中的数据。
ALTER FRAGMENT ONLINE ON TABLE employee
DETACH PARTITION sys_p2 employee3;
如果有并行的会话访问 sys_p2 ,请将锁定模式设置为 WAIT (提交的 ONLINE DETACH 操作要满足的秒数)以保护非互斥访问错误:
SET LOCK MODE TO WAIT 300;
ALTER FRAGMENT ONLINE ON TABLE employee DETACH PARTITION sys_p2 employee3;
Fragments in surviving table after ALTER FRAGMENT ONLINE:
p0 VALUES <200 - range fragment
p1 VALUES <400 - range fragment
sys_p4 VALUES >= 600 AND VALUES <700 - interval fragment.
使用 BYTE 和 TEXT 列拆离
如果 DETACH 子句指定包含 BYTE 或 TEXT 数据类型的简单大对象的表的第一个分片,那么数据库服务器会锁定该表中每个分片的 blobspace 。要拆离该表的其它分片,那么请只锁定指定分片的 blobspaces ,而不是所有分片的 blobspaces ,如果此分片不是第一个那么需要较少的锁。
从受保护的表拆离
如果 DETACH 子句指定安全策略保护的表执行成功的话,数据库服务器会创建受相同安全策略保护的表,并具有相同行安全标签的 IDSSECURITYLABEL 列,和相同受保护的列集合作为初始表。IDSSECURITYLABEL 列有 NOT NULL 约束。只有持有 DBSECADM 角色的用户可以引用 ALTER FRAGMENT 语句中受保护的表。
生成未分片表的拆离
以下示例使用了已分片为两个 dbspace dbsp1 和 dbsp2 的表 cur_acct:
ALTER FRAGMENT ON TABLE cur_acct DETACH dbsp2 accounts;
此示例将 dbsp2 从 cur_acct 的分布方案拆离,并将这些行放入一个新表 accounts 中。表 accounts 现在具有与 cur_acct 相同的结构(列名、列数、数据类型等),但表 accounts 不包含表 cur_acct 中的任何索引和约束。这两个表现在都未分片的。以下示例显示了一个包含三个分片的表:
ALTER FRAGMENT ON TABLE bus_acct DETACH dbsp3 cli_acct;
此语句将 dbsp3 从 bus_acct 的分布方案拆离,并将这些行放入一个新表 cli_acct 中。表 cli_acct 现在具有与 bus_acct 相同的结构(列名、列数、数据类型等),但表 cli_acct 不包含表 bus_acct 的任何索引和约束。表 cli_acct 是一个未分片表,但表 bus_acct 仍是一个分片表。