一种Oracle数据库异常迁移现象的解决方法
2012-08-06刘伟
刘 伟
(武汉铁路局信息技术处,武汉430071)
Oracle数据库应用于很多铁路信息系统中,作为Oracle数据库管理员,经常会使用EXP/IMP工具迁移用户数据,特别是在Oracle 较低的8i和9i版本中。本文针对一种较为异常的数据库迁移现象,利用EXP/IMP、UltraEdit工具给出相应的解决方法。
1 数据库迁移背景
2007年某铁路信息系统迁入到IBM P570小型机,Oracle数据库使用EXP/IMP工具完成了8i到9i的迁移。虽然Oracle数据库目前运行的比较稳定,但仍存在众多的数据库用户使用同一个表空间的问题。随着时间的推移,该表空间的数据文件变得越来越多,表空间变得越来越大,成为了一个必须重视的问题。经过技术人员的讨论,决定先将某个重要的用户数据从该表空间中迁移出来。
这次迁移的工作是:在同一个Oracle数据库中,将A用户从表空间ts1迁移到表空间ts2上,并且表空间ts1是不允许删除的。
这个工作可以利用下面几个步骤来完成:
(1)给A用户使用者发出通知,告之在某个时间段进行数据库维护工作,这个时间段暂停对A用户数据的访问;
(2)在这个时间段,对A用户进行加锁操作;
(3)exp system/system_password file=a.dmp log=a_exp.log owner=a;
(4)记录A用户拥有的权限和角色;
(5)drop user a cascade;
(6)create user a identified by a_password default tablespace ts2 temporary tablespace temp;
(7)grant 记录的权限或角色给用户A;
(8)revoke unlimited tablespace from a;
(9)alter user a quota 0 on ts1;
(10)alter user a quota unlimited on ts2;
(11)alter user a quota unlimited on temp;
(12)imp a/a_password file=a.dmp log=a_imp.log fromuser=a touser=a。
在完成了上述12步操作后,A用户的数据从表空间ts1又迁移回到ts1上了,这次迁移失败。对于这个结果,咨询了相关Oracle专家,分析认为可能是Oracle数据库某方面的一个bug。
接下来,技术人员讨论出了另外一种方法。利用UltraEdit工具编辑a.dmp,将a.dmp中tablespace“TS1”全部替换成tablespace“TS2”,然后再利用更改后的a.dmp完成迁移工作。可是a.dmp的文件大小有20 G,加载到PC机内存编辑过程中频繁死机。此办法针对大容量dmp文件依然不合适。
2 数据库迁移解决方案
利用UltraEdit工具更改dmp文件的方法经证明在本信息系统的数据库上是可以完成不同表空间的迁移。现在的问题集中在dmp文件的大小上。
EXP命令有一个选项ROWS,默认情况下值为Y,表示导出数据行。当把ROWS设置为N时,dmp文件只包含表的结构,而不包括表中的数据。通过加上这个选项,a.dmp文件只有10 M大小。利用UltraEdit工具对a.dmp完成表空间名的替换,特别注意的是2个表空间名字的字节大小要保持一致,否则更改后的dmp文件就不可用了。
a.dmp是不包含数据的,所以还需利用EXP命令导出一个包含数据的dmp文件a_data.dmp。
利用IMP命令完成a.dmp的导入工作。导入的仅是结构,不包含实际数据。当每次IMP完成后,都有信息输出,如图1。
图1 信息输出界面图
图1中about to enable constraints…表示启动该用户内定义的各种约束,包括外键,触发器等。所以在导入a_data.dmp文件前,必须禁用A用户的外键和触发器,否则可能会造成导入工作的错误。可以通过oracle enterprise manager console或者下面的语句来查询外键和触发器:
select constraint_name, table_name from user_constraints where owner='A' and constraint_type=’R’;
select trigger_name,trigger_type from user_triggers where table_owner='A';
可以通过下面的语句来禁用外键和触发器:
alter table table_name disable constraint constraint_name;
alter trigger trigger_name disable;
导入a_data.dmp时,需要对IMP加上参数IGNORE=Y,表示忽略创建错误。由于a.dmp的导入使得表结构已经存在,所以当a_data.dmp导入发现已建表时需要忽略创建错误。
当完成a_data.dmp导入工作,数据库会自动启用该用户的各种约束,包括前面手工禁用A用户的外键和触发器。
完整的操作步骤如下:
(1)给A用户使用者发出通知,告之在某个时间段进行数据库维护工作,这个时间段暂停对A用户数据的访问;
(2)在这个时间段,对A用户进行加锁操作;
(3)exp system/system_password file=a.dmp rows=n log=a_exp.log owner=a;
(4)exp system/system_password file=a_data.dmp log=a_data_exp.log owner=a;
(5)利用UltraEdit工具将a.dmp中tablespace“TS1”全部替换成tablespace “TS2”;
(6)记录A用户拥有的权限和角色;
(7)drop user a cascade;
(8)create user a identified by a_password default tablespace ts2 temporary tablespace temp;
(9)grant 记录的权限或角色给用户A;
(10)revoke unlimited tablespace from a;
(11)alter user a quota 0 on ts1;
(12)alter user a quota unlimited on ts2;
(13)alter user a quota unlimited on temp;
(14)imp a/a_password file=a.dmp log=a_imp.log fromuser=a touser=a;
(15)禁用A用户的外键和触发器;
(16)imp a/a_password file=a_data.dmp ignore=y log=a_data_imp.log fromuser=a touser=a;
经过上述操作后,迁移工作成功。
3 结束语
本文描述了一种较为特殊的Oracle数据库迁移现象,通过3次试验最终得出了切实可行的解决方法。该方法使用了Oracle EXP/IMP和UltraEdit,实施简单并对数据库的正常运行影响较小,具有数据的可恢复性。