近协助客户做空间回收,用户发现备份的数据太大,根据业务情况删除了部分数据,但是发现空间并没有下降多少,他们也发现这个表
有LOB字段,这些字段的空间没有释放,希望协助释放这些空间。
这个空间收缩任务在我上篇文章中已经说明,使用move表的方式实现,也可以使用shrink lob段的方式,这里我们解决一个字段转换的方法
用户之前的某个表字段类型为long造成了move表或者shink lob方式报错,也即是long字段不支持这个操作,虽然经过查询用户表的该字段都是null
值。所以,这里需要做数据类型转换,将long 转换为clob或者blob
这里我们做一个测试,该测试基于MOS文档Doc ID 251417.1。这里需要注意,原表必须要有主键。下面是具体步骤
[oracle@rac1 ~]$ sqlplus / as sysdba
SQL*Plus: Release 11.2.0.4.0 Production on Sat Nov 21 08:56:35 2020
Copyright (c) 1982, 2013, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Real Application Clusters and Automatic Storage Management options
SYS@orcl1>connect test/oracle
Connected.
TEST@orcl1>show user;
USER is "TEST"
1 创建测试表 插入数据
TEST@orcl1>CREATE TABLE TLONG (ID NUMBER PRIMARY KEY, SOME_FILE LONG);
Table created.
TEST@orcl1>insert into tlong values (1,'duiheduedfefefj');
1 row created.
Elapsed: 00:00:00.04
TEST@orcl1>commit;
Commit complete.
Elapsed: 00:00:00.00
TEST@orcl1>select * from tlong;
ID SOME_FILE
---------- --------------------------------------------------------------------------------
1 duiheduedfefefj
Elapsed: 00:00:00.01
2 创建中间表tlob 与tlong相同表结构,注意对应字段为clob类型,来代替tlong中的long类型。这个表不需要主键
TEST@orcl1>CREATE TABLE TLOB (ID NUMBER, SOME_FILE CLOB);
Table created.
Elapsed: 00:00:00.01
TEST@orcl1>desc tlob
Name Null? Type
----------------------------------------------------------------- ----
ID NUMBER
SOME_FILE CLOB
3 测试表tlong具备在线中定义的条件
TEST@orcl1>EXECUTE DBMS_REDEFINITION.CAN_REDEF_TABLE('test','tlong', dbms_redefinition.cons_use_pk);
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01
4 实施重定义
TEST@orcl1>EXECUTE DBMS_REDEFINITION.START_REDEF_TABLE('test','tlong','tlob', 'id id, to_lob(some_file) some_file', dbms_redefinition.cons_use_pk);
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.74
5 配置在表tlob上自动创建数据库对象如触发器,索引和约束,具体参数需求根据实际情况可以调整
TEST@orcl1>EXECUTE DBMS_REDEFINITION.START_REDEF_TABLE('test','tlong','tlob', 'id id, to_lob(some_file) some_file', dbms_redefinition.cons_use_pk);
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.74
TEST@orcl1>declare
2 num_errors BINARY_INTEGER;
3 BEGIN
4 DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('test' ,'tlong','tlob',0,TRUE,TRUE,TRUE,FALSE,num_errors,TRUE,FALSE);
5 END;
6 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:05.06
6 同步数据,这个步骤可选,主要是加快数据同步,在第4步已经开始同步数据。
TEST@orcl1>EXECUTE DBMS_REDEFINITION.SYNC_INTERIM_TABLE('test', 'tlong','tlob');
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.06
7 完成表的在线中定义
TEST@orcl1>EXECUTE DBMS_REDEFINITION.FINISH_REDEF_TABLE('test','tlong','tlob');
PL/SQL procedure successfully completed.
Elapsed: 00:00:02.96
TEST@orcl1>desc tlong;
Name Null? Type
----------------------------------------------------------------------------------------------------------------- --------
ID NUMBER
SOME_FILE CLOB
TEST@orcl1>select * from tlong;
ID SOME_FILE
---------- --------------------------------------------------------------------------------
1 duiheduedfefefj
Elapsed: 00:00:00.00
8 删除中间表
TEST@orcl1>drop table tlob purge;
Table dropped.
Elapsed: 00:00:00.19
Oracle的表在线重定义,通过中间表将数据,库对象同步过来,修改原始表字段类型等操作,业务小化业务影响,Oracle只有想不到,没有XXX。
测试完毕!